OpenACC GFortran Interoperability with CUDA libraries

Fortran interface files for the FORTRAN CUDA Library based on their corresponding header files provided by the CUDA Toolkit are publicly available on GitHub: https://github.com/MentorEmbedded/fortran-cuda-interfaces. They contain modules cublas_v2, cublas (legacy CUBLAS interface), cublasxt (multi-GPU host interface), openacc_cublas (interface for OpenACC device code regions), and cufft, which can be utilized by adding the following lines at the beginning of a Fortran program, function or subroutine:

use cublas_v2
use cublas
use cublasxt
use openacc_cublas
use cufft

The following program demonstrates how to use cublasSaxpy with gfortran.

program test
  use cublas
  implicit none

  integer, parameter :: N = 10
  integer :: i
  real*4 :: x_ref(N), y_ref(N), x(N), y(N), a

  a = 2.0

  do i = 1, N
     x(i) = 4.0 * i
     y(i) = 3.0
     x_ref(i) = x(i)
     y_ref(i) = y(i)
  end do

  call saxpy (N, a, x_ref, y_ref)

  !$acc data copyin (x) copy (y)
  !$acc host_data use_device (x, y)
  call cublassaxpy(N, a, x, 1, y, 1)
  !$acc end host_data
  !$acc end data

  do i = 1, N
     if (y(i) .ne. y_ref(i)) call abort
  end do
end program test

subroutine saxpy (nn, aa, xx, yy)
  integer :: nn
  real*4 :: aa, xx(nn), yy(nn)
  integer i
  real*4 :: t
  !$acc routine

  do i = 1, nn
    yy(i) = yy(i) + aa * xx(i)
  end do
end subroutine saxpy

To build and run this example, issue the following commands:

$gfortran -fopenacc cublas-test.f90 -lcublas
$ ./a.out

You may need to add -L/path/to/cuda/lib if CUDA is not installed in a standard location. At present, the CUDA interface files for Fortran include support for calling CUBLAS and CUFFT functions from the host. As the example demonstrates, the on-device data for those CUDA functions can be managed by OpenACC. However, the CUDA functions cannot be called from within OpenACC parallel or kernels regions.

The CUDA interface files support the functions defined in CUDA 9. If new functions are added to CUDA in a later release, they can be called directly in GFortran manually by writing new function interfaces for them. For example, to call cublassaxpy from Fortran, use the following interface block.

interface
   subroutine cublassaxpy(N, alpha, x, incx, y, incy) bind(c, name="cublasSaxpy")
     use iso_c_binding
     integer(kind=c_int), value :: N
     real*4, value :: alpha
     type(*), dimension(*) :: x
     integer(kind=c_int), value :: incx
     type(*), dimension(*) :: y
     integer(kind=c_int), value :: incy
   end subroutine cublassaxpy
end interface

The arguments passed to cublassaxpy must be declared as host_data. A more complete example can be found here:

https://gcc.gnu.org/ml/gcc-patches/2016-08/msg00976.html

None: OpenACC/GFortran Interoperability with CUDA libraries (last edited 2020-07-01 13:05:53 by tschwinge)