使用 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 到。
我一直在尝试编译和 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 到。