Problem using Cuda as a static library with C++ and Fortran on VS2012

Hello,

So In my company where we program computing programs for structural mechanics, we decided to try using cuda for GPU computing and I was given the mission to test it and try to use it with a Fortran program we already developed.

I understood how to use Cuda in C along with the library cublast. Now I want to test launching a cuda calculus from fortran. So I have the following fortran main program (fortranF.f90)

program fortran
	
use	appelc
implicit none

integer itaille
real, allocatable :: matr1(:), matr2(:), matr3(:)

allocate(matr1(itaille*itaille),matr2(itaille*itaille),matr3(itaille*itaille))
matr3 = 0

matr1 = 2
matr2 = 3

call monde

call mulmat(matr1,matr2,matr3,itaille)

PAUSE 1

end program fortran

With the corresponding module (moduleC.f90):

module appelc
interface

subroutine mulmat(A,B,C,N) bind(C,NAME='matcal')
use,intrinsic :: ISO_C_BINDING ! Declares C kinds
real(c_float),intent(in) :: A(*)
real(c_float),intent(in) :: B(*)
real(c_float),intent(out) :: C(*)
integer(c_int),intent(in) :: N
end subroutine mulmat

end interface
end module appelc

I also have a C++ project compiled as a static library, with only one file (LibC++.cpp):

#include "simpleCUBLAS.h"

extern "C"
{
 void matcal(float *A, float *B, float *C, int &taille)
 {
  fortcublas(A,B,C,taille);
 }
}

For cuda I use the same file in simpleCUBLAS sample example transforming the main into the fortcublas function. The cuda project is also compiled as static library.

The problem is when I try to build it seems fortran gets to lauching the fortcublas function but doesn’t recognise different cuda and cublas functions:

Erreur	12	 fatal error LNK1120: 11 externes non résolus	x64\Debug\Fortran.exe
Erreur	5	 error LNK2019: symbole externe non résolu cudaMalloc référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	6	 error LNK2019: symbole externe non résolu cudaFree référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	3	 error LNK2019: symbole externe non résolu cudaEventSynchronize référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	2	 error LNK2019: symbole externe non résolu cudaEventRecord référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	4	 error LNK2019: symbole externe non résolu cudaEventElapsedTime référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	1	 error LNK2019: symbole externe non résolu cudaEventCreate référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	11	 error LNK2019: symbole externe non résolu cublasSgemm_v2 référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	9	 error LNK2019: symbole externe non résolu cublasSetVector référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	10	 error LNK2019: symbole externe non résolu cublasGetVector référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	8	 error LNK2019: symbole externe non résolu cublasDestroy_v2 référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)
Erreur	7	 error LNK2019: symbole externe non résolu cublasCreate_v2 référencé dans la fonction "void __cdecl fortcublas(float *,float *,float *,int)" (?fortcublas@@YAXPEAM00H@Z)	simpleCUBLAS.lib(simpleCUBLAS.obj)

I know I made it compilcated using fortran to call c++ then to call cuda, but I didn’t find how to do it directly.

Do anyone know how to solve this problem ? Thanks.

It used to be that CUBLAS entry points were C-style (non-decorated) functions, and therefore directly callable from Fortran without even using ISO-C bindings on the Fortran side (which does not mean use of ISO-C bindings isn’t a good idea).

You did not show your build commands, the error you get from the linker suggests that either the build is not actually linking against the CUBLAS library, or that there is possibly a C/C++ interface mismatch (i.e., name decoration vs lack of name decoration for function calls).

You need to link the cuda runtime and cublas libraries.
Since your code is in Fortran, you should consider using CUDA Fortran from PGI, there is now a free community edition.
PGI provides all the Fortran binding to cublas and other numerical CUDA libraries.

Thank you I managed to solve the problem. I needed to add cudart.lib and cublas.lib in the linker propreties in VS2012.