Cuda & fortran简单的例子

来源:互联网 发布:python开源应用 编辑:程序博客网 时间:2024/05/20 19:31

一、 简单小程序

module simpleOps_mcontains attributes(global)subroutine increment(a,b)  implicit none  integer,intent(inout)::a(:)  integer,value::b  integer::i  i = threadIdx%x  a(i)=a(i)+b end subroutine incrementend module simpleOps_mprogram incrementTestGPU  use cudafor  use simpleOps_m  implicit none  integer ,parameter :: n =256  integer :: a(n),b  integer, device :: ad(n)  a=1  b=3  ad=a  call increment<<<1,n>>>(ad,b)  a=ad  if(any(a /=4)) then    write(*,*) "Failed"  else    write(*,*)  "Passed"  endifend program incrementTestGPU

fortran是用module进行包装的。implicit none这句表示变量必须定义之后才可以使用,subroutine是用来包装子程序的标签,(global)这个相当于cuda的__global__。Fortran的参数申明是在里面的,不需要在increment(a,b)这个里面做申明。Increment是子程序名。Fortran默认是按地址传递,所以如果要使用按值传递的话,需要加上value这个形容词,就比如上面的integer,value::b一样。Program是程序的入口,就像main一样,incrementTestGPU这个是程序名称可以修改成其他,use cudafor这个是需要添加的因为我们会使用到cudaFortran。simpleOps_m这个模块我也也会使用到,我们会调用到里面的子程序。然后就定义各种变量,大家注意格式就好了。调用内核函数的使用,和cuda一样,只是多了一个call这个东西。
如果我们把上面的代码存在a.f90
编译命令:pgf90 a.f90 -Mcuda
-Mcuda这个参数是需要添加的,它是为了告诉编译器我要使用到cudaFortran了。


二、 调用另外一个文件的内核函数

假如我们把内核函数写在b.f90这个文件里面

module simpleOps_mcontains attributes(global)subroutine increment(a,b)  implicit none  integer,intent(inout)::a(:)  integer,value::b  integer::i  i = threadIdx%x  a(i)=a(i)+b end subroutine incrementend module simpleOps_m

我们把主函数写在a.f90这个文件里面

program incrementTestGPU  use cudafor  use simpleOps_m  implicit none  integer ,parameter :: n =256  integer :: a(n),b  integer, device :: ad(n)  a=1  b=3  ad=a  call increment<<<1,n>>>(ad,b)  a=ad  if(any(a /=4)) then    write(*,*) "Failed"  else    write(*,*)  "Passed"  endifend program incrementTestGPU
这个时候我们就涉及到调用另外一个文件里的函数的问题,其实很简单。我们先把b.f90这个文件编译成.o的中间文件即可,只是注意需要加个参数编译命令:pgf90  -Mcuda=rdc  -c  b.f90这个时候就生成了b.o这个文件pgf90  -Mcuda  b.o  a.f90这个时候我们就可以看到可执行文件了。

0 0