【问题标题】:Unresolved reference to dgemm when using OpenBLAS使用 OpenBLAS 时未解决对 dgemm 的引用
【发布时间】:2020-09-01 19:34:48
【问题描述】:

一段时间以来,我一直在尝试使用 dgemm 编译和链接 OpenBLAS 库以将矩阵相乘。在使用 pacman 从 MSYS2 安装 MSYS2 和 mingw64 包后,我终于能够编译 OpenBLAS。我的意图是将 OpenBLAS 用作静态库。所以我写了一个简单的 fortran 代码来使用 dgemm 将矩阵相乘。这是fortran代码:

program gcc_fun

 implicit none
            
! Variables
 real*8 x(2,2),y(2,2),z(2,2)

 x(1,1) = 3.d0
 x(2,1) = 2.d0
 x(1,2) = 1.d0
 x(2,2) = 4.d0
 y(1,1) = .5d0
 y(2,1) = 1.d0
 y(1,2) = 2.d0
 y(2,2) = .75d0
 
    call dgemm( 'n', 'n', 2, 2, 2, 1,x,2,y, 2, 1, z, 1)

! Body of gcc_fun
print *, 'Z = ', z

end program gcc_fun

这是我尝试链接的makefile:

CCC      = gcc   -g -Iincludem -Iincludev   -c   -O0
WARN     = -Wall
CCCX     = x86_64-w64-mingw32-g++  -m64 -s -Iincludem -Iincludev   -c   -O2 -DNDEBUG
fort     = x86_64-w64-mingw32-gfortran -s -Iincludem -Iincludev -fno-underscoring -c   -O2 -DNDEBUG
#fort     = x86_64-w64-mingw32-gfortran -s -Iincludem -Iincludev -c   -O2 -DNDEBUG

OBJECTS = \
     obj/gcc_fun.o 



          
#-----------------------------------------------------------------------------------
#  Make the Guidance Object Library (GNC_Lib.a) and the Executable (guideUnitTest)
#-----------------------------------------------------------------------------------


gcc_fun.exe:  $(OBJECTS)
    x86_64-w64-mingw32-gfortran -o gcc_fun.exe   -L./ -lopenblas_haswell-r0.3.10  $(OBJECTS) 

#------------------------------------------
#                object file targets 
#------------------------------------------

    
obj/gcc_fun.o: \
gcc_fun.f90
    $(fort) $(WARN) -o $@ gcc_fun.f90

我使用make -f makefile_name 运行make 文件并获得对dgemm 的未解析引用。我已经尝试过使用和不使用无下划线选项都无济于事。这是实际的错误:

$ make -f Makefile_gcc_fun.mak
x86_64-w64-mingw32-gfortran -s -Iincludem -Iincludev -fno-underscoring -c   -O2 -DNDEBUG -Wall -o obj/gcc_fun.o gcc_fun.f90
f951.exe: Warning: Nonexistent include directory 'includem' [-Wmissing-include-dirs]
f951.exe: Warning: Nonexistent include directory 'includev' [-Wmissing-include-dirs]
gcc_fun.f90:27:2:

   27 |   x(2,1) = 2.d0
      |  1
Warning: Nonconforming tab character at (1) [-Wtabs]
gcc_fun.f90:28:2:

   28 |   x(1,2) = 1.d0
      |  1
Warning: Nonconforming tab character at (1) [-Wtabs]
gcc_fun.f90:29:2:

   29 |   x(2,2) = 4.d0
      |  1
Warning: Nonconforming tab character at (1) [-Wtabs]
gcc_fun.f90:31:2:

   31 |   y(2,1) = 1.d0
      |  1
Warning: Nonconforming tab character at (1) [-Wtabs]
gcc_fun.f90:32:2:

   32 |   y(1,2) = 2.d0
      |  1
Warning: Nonconforming tab character at (1) [-Wtabs]
gcc_fun.f90:33:2:

   33 |   y(2,2) = .75d0
      |  1
Warning: Nonconforming tab character at (1) [-Wtabs]
x86_64-w64-mingw32-gfortran -o gcc_fun.exe   -L./ -lopenblas_haswell-r0.3.10  obj/gcc_fun.o
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: obj/gcc_fun.o:gcc_fun.f90:(.text+0xf5): undefined reference to `dgemm'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile_gcc_fun.mak:19: gcc_fun.exe] Error 1

当我用 nm 检查 OpenBLAS 库时,我得到了这个:

$ nm -g libopenblas_haswell-r0.3.10.a | grep dgemm
dgemm.obj:
0000000000000000 T dgemm_

所以看起来 dgemm 是一个外部对象,我应该可以调用它。我确定我错过了一些简单的东西,所以感谢您的帮助。

【问题讨论】:

    标签: fortran gfortran mingw-w64 msys2 openblas


    【解决方案1】:

    子程序只是dgemm,而不是dgemm_。你就叫吧

    call dgemm()
    

    您使用nm 看到的符号名称可能因您的工具链(编译器、操作系统...)而异。如果您进行不同编程语言的互操作性,这很重要。但是,如果您使用 Fortran,则无需担心没有它。


    重要:

    被链接的静态库应该放在在链接命令中使用该库的文件之后。只有这样才能解决依赖关系。如果这是实际问题,我们将提供一些重复链接。

    【讨论】:

    • 感谢您的评论。我只用call dgemm 尝试过,错误变为undefined reference to dgemm
    • @DavidAlldredge 但是你为什么使用-fno-underscoring?或者它是不是真的使用过? Makefile 中fort 的用途是什么?有没有用过?
    • 这个简单的例子源于我的实际应用程序,它是混合 fortran、c、c++ 代码。我需要fortran不附加“_”。所以没有下划线选项。在这个简单的例子中,我只是想让它工作,然后再转向更大、更复杂的应用程序。由于这是我第一次尝试链接 OpenBLAS ,我不确定我是否使用 mingw_w64 交叉编译器正确编译了它。如果这个简单的例子应该如图所示,那么我猜我是如何编译 OpenBLAS 的?
    • 我刚刚看到您修改后的评论。我定义了fort,然后用它来编译显示在本页顶部的.f90 文件。
    • @DavidAlldredge 但是您显示的编译器输出中没有--fno-underscoring。我根本看不到fort 是如何使用的。请发布完整的输出,包括所有编译步骤。在此之前创建一个make clean(或删除所有 .o 文件)。
    猜你喜欢
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多