使用 OpenBLAS 时未解决的对 dgemm 的引用

Unresolved reference to dgemm when using OpenBLAS

我一直在尝试编译和 link OpenBLAS 库以使用 dgemm 一起乘以矩阵。在使用 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 link:

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 生成文件并获得对 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 是一个外部对象,我应该可以调用它。我确定我遗漏了一些简单的东西,所以感谢您的帮助。

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

call dgemm()

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


重要:

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