FortranからCUDAを呼ぶその2:CUDAをFortranから呼び出してみる

CUDAを呼び出してみます。題材とさせて貰うのは、GPGPU 勉強会 - CUDA Samples配列の足し算/最低限 GPGPUです。
vecadd_v1.cu→「vecadd_v1_CUDA.cu, vecadd_v1_main.f90」へと書き換えました。以下code例です。

vecadd_v1_CUDA.cu

#include <stdio.h>

// 配列の足し算を行う関数
__global__ void vecadd(float *x, float *y, float *z, int N)
{
  int i;
  for(i = 0; i < N; i++)
    z[i] = x[i] + y[i];
}

void vecaddv1(float *x, float *y, float *z, int N)
{
//  int N=10;  // 配列のサイズを指定する
  int i, size;
//  float x[N], y[N], z[N];
  float *xd, *yd, *zd;

  // 初期値の設定
//  for(i = 0; i < N; i++)
//  {
//    x[i] = i + 1.0;
//    y[i] = i + 2.0;
//  }

  // デバイスメモリの確保
  size = N * sizeof(float);
  cudaMalloc((void**)&xd, size);
  cudaMalloc((void**)&yd, size);
  cudaMalloc((void**)&zd, size);

  // ホスト側のデータをデバイス側にコピー
  cudaMemcpy(xd, x, size, cudaMemcpyHostToDevice);
  cudaMemcpy(yd, y, size, cudaMemcpyHostToDevice);

  // ここで足し算を行う
  vecadd<<<1, 1>>>(xd, yd, zd, N);

  // デバイス側のデータをホスト側にコピー
  cudaMemcpy(z, zd, size, cudaMemcpyDeviceToHost);

  // 出力
  for(i = 0; i < N; i++)
  {
    printf("%d: %f\n", i, z[i]);
  } 

  // デバイスメモリの開放
  cudaFree(xd);
  cudaFree(yd);
  cudaFree(zd);

}

extern "C" void vecaddv1_(float *x, float *y, float *z, int *N)
{
   vecaddv1(x, y, z, *N);
}

vecadd_v1_main.f90

program vecadd_v1_main

  implicit none
  
  integer, parameter:: N=10  !  配列のサイズを指定する
  integer:: i
  real(4):: x(N), y(N), z(N)
  
! 初期値の設定
 
  do i=1,N
     x(i)=i-1 + 1.0
     y(i)=i-1 + 2.0
  enddo

! ここで足し算を行う

  call vecaddv1(x, y, z, N);

! 出力

  do i=1,N
     write(*,*)i, z(i)
  enddo
  
end program vecadd_v1_main

実行

% nvcc -c vecadd_v1_CUDA.cu
% ifort vecadd_v1_CUDA.o vecadd_v1_main.f90 -o vecadd_v1.exe -lcudart -L/usr/local/cuda/lib64/
% ./vecadd_v1.exe

実行結果

0: 3.000000
1: 5.000000
2: 7.000000
3: 9.000000
4: 11.000000
5: 13.000000
6: 15.000000
7: 17.000000
8: 19.000000
9: 21.000000
           1   3.000000    
           2   5.000000    
           3   7.000000    
           4   9.000000    
           5   11.00000    
           6   13.00000    
           7   15.00000    
           8   17.00000    
           9   19.00000    
          10   21.00000  

FortranからCUDAを呼び出すときに注意すること(書きかけ)