Search code examples
fortrangfortranmingw-w64msys2openblas

Unresolved reference to dgemm when using OpenBLAS


I have been trying for some time to compile and link the OpenBLAS lib to multiply to matrices together using dgemm. I finally was able to compile the OpenBLAS after installing MSYS2 and the mingw64 packages from MSYS2 using pacman. My intention is to use the OpenBLAS as a static lib. So I wrote a simple fortran code to multiply the matrices together using dgemm. Here is the fortran code:

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

Here is my makefile to try and 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

I run the make file with make -f makefile_name and get unresolved reference to dgemm. I have tried it with and without the no-underscoring option to no avail. Here is the actual error:

$ 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

When I inspect the OpenBLAS library with nm I get this:

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

So it looks like dgemm is an external object and I should be able to call it. I am sure I am missing something easy so thanks for any help.


Solution

  • The subroutine is just dgemm, not dgemm_. You just call it

    call dgemm()
    

    The symbol name you see using nm can differ depending on your toolchain (compiler, operating system,...). It matters if you do interoperability of different programming languages. However, if you stay within Fortran, you do not need to worry without it.


    Important:

    The static library being linked should be placed after the file that uses the library in the linking command. Only then the dependecies can be resolved. If this is the actual issue, we will have some duplicates to link to.