[转贴]fortran调用CUDA

  • 0 replies
  • 2671 views
*

sisiy

  • *****
  • 246
    • 查看个人资料
[转贴]fortran调用CUDA
« 于: 二月 17, 2012, 07:28:09 pm »
和Fortran调用C代码一样,问题很简单,就是混合编译的问题,基本思路是:C/CUDA 代码写一个文件。Fortran代码写一个文件。各自独立编译compile, 生成-obj文件,然后链接。
只不过写的时候有讲究了。比如在fortran 的test 中调用一段cuda:其中C代码为:#include
#include
#include
extern "C" void helloworldcuda_ ()
{
printf("Hello world CUDA Routine !!\n");
int deviceCount;
int dev;
cudaGetDeviceCount(&deviceCount);
dev=0;
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, dev);
printf("\nDevice %d: on %d \"%s\"\n", dev, deviceCount, deviceProp.name);
};

其中Fortran代码为program test
implicit none
print *,"Hello World from Fortran"
call helloworldcuda()
end program test然后编译cuda 代码nvcc -c trycuda.cu 然后链接和编译到Fortran代码ifort -o test -L /usr/local/cuda/lib -lcudart trycuda.o tryf.f90然后运行./test注: 该例子来自:http://forums.nvidia.com/index.php?showtopic=151886


fortran一般开的是数组。而C用的是指针?这该怎么办?Fortran的索引从1开始而且是collmn major,C从0开始,而且是row major怎么办?幸好,Nvidia给了个小的解决方案,就是在cublas中。引入了几个API,CUBLAS_SET_VECTOR, CUBLAS_GET_VECTOR,CUBLAS_SET_MATRIX, and CUBLAS_GET_MATRIX).定义在/usr/local/cuda/src 的fortran.c中这几个API的作用是分配device变量的指针和相互拷贝Host和device中内存。编程人员可以直接在f90文件中调用这些函数。
具体,必须将fortran.c拷入你当前的工作目录。然后编译nvcc -c fortran.c 生成了fortran.o然后和你的fortran程序(比如test.f90)进行链接:ifort -o test -L /usr/local/cuda/lib -lcudart -lcublas fortran.o test.f90注意-lcublas不能少。然后./test
具体的那几个api的使用必须查看nvidia的cublas.pdf


Fortran方面声明为数组:如: real, allocatable :: f(:,:,:),df(:,:,:)     integer :: nx     integer :: ny     integer :: ny     nx=100     ny=100     nz=100     allocate (df(nx,ny,nz))     allocate ( f(nx,ny,nz))
call cuda_diff(df, f, nx, ny, nz)
而C 代码中这样写:extern "C"void cuda_diff_(float *f, float *df, int *nx, int *ny, int *nz){int x=*nx;....}所以必须注意,nx,ny,nz前面必须有*。而C函数前必须有下划线。
Fortran不区分大小写,并且把在code中所有的大写字母全部识别为小写。而CUDA和C区分大小写。这样在命名函数的时候,CUDA和C的函数如果含有大写字母,那么fortan call cuda 的时候就会报错,找不到XX这个函数。
查看原文 :http://blog.sina.com.cn/dtx08