fortran cuda interface passing pointer from fortran and allocating memory on device

Hello,
I intend to pass pointer to cuda code and get it allocated a chunk on memory on device. Following is my code. Its getting compiled well, but output is incorrect. Can anyone help me out ?
FORTRAN code:–

PROGRAM memtest
USE iso_c_binding
INTERFACE
SUBROUTINE get_in(x,n) BIND(C,name=“get_in”)
USE iso_c_binding
TYPE(C_PTR) :: x
INTEGER(C_INT),VALUE :: n
END SUBROUTINE
END INTERFACE
TYPE(C_PTR) :: px
INTEGER,POINTER :: x( : )
INTEGER(C_INT) :: n=10
CALL get_in(px,n)
END PROGRAM

CUDA-Program in C
#include<stdlib.h>
#include<stdio.h>

extern “C” void get_in(int **x,int n)
{

int y=(int)calloc(n,sizeof(int));
y[0]=10;
x=(int**)malloc(sizeof(int*));

cudaMalloc((void**)x,nsizeof(int));
cudaMemcpy(x[0],y,n
sizeof(int),cudaMemcpyHostToDevice);
y[0]=11;

printf("\ny0=%d",y[0]);
cudaMemcpy(y,x[0],n*sizeof(int),cudaMemcpyDeviceToHost);
printf("\ny0=%d",y[0]);

}
compilers used: gcc 4.3.3
nvcc: release 3.0, V0.2.1221
Ideal output:
y0=11
y0=10

Actual output
y0=10
y10=10

Can anyone point out possible bug in my code ?

thanks and regards,
Nachiket

All arguments in Fortran code are passed as pointers, so any C/C++ code called by Fortran must also have pointer arguments, not pass-by-value or pass-by-reference. It means that the CUDA calls are probably failing on the n value you pass, but you have no error checking and don’t see it.

Yes. But gcc-4.3.3 comes with a support for passing arguments by value as well as reference in FORTRAN. If you notice, the data-type for arguments of function get_in is C_PTR and C_INT. Its called C-Interoperability. This feature has been added from FORTRAN 2003 onwards. Instead of CUDA code if I allocate memory to a pointer in C code, this code is running absolutely fine.

Btw. there is a typo in what I have written:

Actual output:

y0=11

y0=11

Indeed, it seems the C interop stuff acutally works in gfortran 4.3 (it certainly didn’t work well last time I tries it, which was circa gfortran 4.1 or whatever Redhat shipped with ES5.1).

This worked for me:

avidday@cuda:~/code/fortrancuda$ gcc -c -I$CUDA_INSTALL_PATH/include fcuda.c -o fcuda.o

avidday@cuda:~/code/fortrancuda$ gfortran -o memtest memtest.f90 fcuda.o -L/opt/cuda-3.0/lib64/ -lcudart

avidday@cuda:~/code/fortrancuda$ ./memtest 

y[0](before)=11

y[0](after)=10

avidday@cuda:~/code/fortrancuda$ cat fcuda.c

#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

#include "cuda_runtime.h"

#ifndef gpuAssert

#include <stdio.h>

#define gpuAssert( condition ) { if( (condition) != 0 ) { fprintf( stderr, "\n FAILURE %s in %s, line %d\n", cudaGetErrorString(condition), __FILE__, __LINE__ ); exit( 1 ); } }

#endif

void get_in(int **x,int n)

{

	int *y=(int*)calloc(n,sizeof(int));

	y[0]=10;

	gpuAssert( cudaMalloc((void**)x,n*sizeof(int)) );

	gpuAssert( cudaMemcpy(*x,y,n*sizeof(int),cudaMemcpyHostToDevice) );

	y[0]=11;

	printf("y[0](before)=%d\n",y[0]);

	gpuAssert( cudaMemcpy(y,*x,n*sizeof(int),cudaMemcpyDeviceToHost) );

	printf("y[0](after)=%d\n",y[0]);

	free(y);

}

Hello,

I compiled your code successfully but failed to run it. I received following error:
FAILURE CUDA version is insufficient for CUDART version in alloc_mem.cu, line 43

Also I have one more query:

How did you manage to compile without prefixing the function get_in with extern “C” ? For me it did not work.

thanks and regards,
Nachiket

The driver you are using is too old for the CUDA version you have. For CUDA 3.0 you must use a 195 series driver on Linux.

As you can see, I compiled the CUDA containing function as plain C using gcc. There is no device code, so there is no need to use nvcc in this case - nvcc uses C++ host code compilation by default, although this can be changes from the command line if you don’t want host code compiled as C++.

Hello,

My machine is Tesla. I am not sure whether 195 series is appropriate for it. Anyways thanks for reply.

On linux, the driver is common between consumer Geforce and Telsa cards. You won’t get this to work unless the SDK and driver versions match. Either downgrade to an older SDK version or upgrade the driver.

Okay. Will try this solution. Thanks!