使用C包装器在Fortran程序中分配CUDA固定内存(WITHOUT PGI CUDA Fortran)

时间:2017-04-23 23:31:32

标签: cuda fortran fortran-iso-c-binding

我试图让一个Fortran程序(主)写入/读取由CUDA C / C ++分配的固定内存,但是测试显示来自C包装器的偶数DenseBase<Derived>将返回错误。

Fortran访问CUDA C / C ++ Block<...>内存可以在"Passing allocatable array from fortran to C and malloc it"之后完成,但是,只需用cudaHostAlloc替换mallocmalloc将返回{{ 1}}(可以成功编译)。

ifort用于Fortran。以下是无效代码: *已编辑以包含整个脚本

cudaMallocHost

cudaHostAlloc

cudaErrorMemoryAllocation

输出:

//CUDA C/C++ host function in "cudaMallocHost.cu"
#include <cuda.h>
#include <cuda_runtime_api.h>
#include <cstdio>

extern "C" {
int *alloc_test(size_t size) {
    int *a;
    size_t fm, gm;
    cudaMemGetInfo(&fm, &gm);
    printf("GPU memory usage: %lu/%lu MB\n", fm / 1024 / 1024,
            gm / 1024 / 1024);
    cudaHostAlloc((void **) &(a), sizeof(int) * size, cudaHostAllocDefault);
    printf("%s\n", cudaGetErrorString(cudaGetLastError()));
    //       a=(int*) malloc(sizeof(int) * 4);  // 'malloc' works
    return a;
}
void destroy_test(int *ptr) {
    cudaFreeHost(ptr);
    printf("%s\n", cudaGetErrorString(cudaGetLastError()));
    //       free(ptr);
}
}

Fortran主程序中! FORTRAN program in "main.f" PROGRAM fortran_side USE ISO_C_BINDING IMPLICIT NONE INTERFACE FUNCTION alloc_test(s) BIND(C, NAME='alloc_test') USE ISO_C_BINDING IMPLICIT NONE TYPE(C_PTR) :: alloc_test INTEGER(C_SIZE_T) :: s END FUNCTION alloc_test SUBROUTINE destroy_test(p) BIND(C, NAME='destroy_test') USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR IMPLICIT NONE TYPE(C_PTR), INTENT(IN), VALUE :: p END SUBROUTINE destroy_test END INTERFACE TYPE(C_PTR) :: p INTEGER(C_INT), POINTER :: array(:) INTEGER(C_SIZE_T) :: sz INTEGER(4) :: i sz=4 p = alloc_test(sz) CALL C_F_POINTER(p, array, [sz]) DO i=1,sz array(i)=i*3 END DO PRINT*,array CALL destroy_test(p) END PROGRAM fortran_side 是否可行?我已经尝试了PGI CUDA Fortran,它可以很容易地完成这项工作,而不涉及Fortran / C混合编程。我也尝试过纯CUDA #Makefile all: cudaMallocHost.o main.f ifort -L/Developer/NVIDIA/CUDA-8.0/lib -lcudart -lcufft -O0 -132 \ cudaMallocHost.o main.f -o ./test clean: rm -f *.o *.mod ./test %.o: %.cu nvcc -arch sm_30 -O0 -c $*.cu -o $*.o ,它也适用于我的系统(Mac)。

1 个答案:

答案 0 :(得分:2)

C函数

int *alloc_test(size_t size) 

按值估计其参数,但您的Fortran接口通过引用

传递它
    FUNCTION alloc_test(s) BIND(C, NAME='alloc_test')
      ...
      INTEGER(C_SIZE_T) :: s

通过值使用传递

      INTEGER(C_SIZE_T), VALUE :: s