打电话给CUDA" Hello World"来自Haskell使用FFI会得出错误的结果

时间:2015-05-25 16:37:10

标签: haskell cuda ffi

这是标准的Hello World CUDA文件:

#include <stdio.h>
#include "hello.h"

const int N = 7;
const int blocksize = 7;

__global__ void hello_kernel(char *a, int *b) {
    a[threadIdx.x] += b[threadIdx.x];
}

#define cudaCheckError() { \
    cudaError_t e=cudaGetLastError(); \
    if(e!=cudaSuccess) { \
        printf("Cuda failure %s:%d: '%s'\n",__FILE__,__LINE__,cudaGetErrorString(e)); \
        exit(0); \
    } \
}

void hello() {
    char a[N] = "Hello ";
    int b[N] = {15, 10, 6, 0, -11, 1, 0};

    char *ad;
    int *bd;
    const int csize = N*sizeof(char);
    const int isize = N*sizeof(int);

    printf("%s", a);

    cudaMalloc( (void**)&ad, csize );
    cudaMemcpy( ad, a, csize, cudaMemcpyHostToDevice );
    cudaCheckError();

    cudaMalloc( (void**)&bd, isize );
    cudaMemcpy( bd, b, isize, cudaMemcpyHostToDevice );
    cudaCheckError();

    dim3 dimBlock( blocksize, 1 );
    dim3 dimGrid( 1, 1 );
    hello_kernel<<<dimGrid, dimBlock>>>(ad, bd);
    cudaMemcpy( a, ad, csize, cudaMemcpyDeviceToHost );
    cudaCheckError();

    cudaFree( ad );
    cudaCheckError();

    printf("%s\n", a);
}

其标题:

-- hello.h
extern "C" 
void hello();

这是一个调用这种函数的Haskell文件:

-- test.hs
{-# LANGUAGE ForeignFunctionInterface #-}

import Foreign.C
import Foreign.Ptr (Ptr,nullPtr)

foreign import ccall "hello" hello :: IO ()

main = hello

我正在编译:

nvcc hello.c -c -o hello.o
ghc test.hs -o test hello.o -L/usr/local/cuda/lib -optl-lcudart

使用./test运行该程序会导致:

Hello Cuda failure hello.cu:32: 'no CUDA-capable device is detected'

正如预期的那样,使用只调用main()的C hello运行相同的程序会产生Hello World

如何让Haskell正确检测设备?

2 个答案:

答案 0 :(得分:5)

也许无关,但我能够在Mac上使用单独的板载和独立显卡重现您的错误。当&#34;自动图形切换&#34;在系统偏好设置中启用(并且没有运行3D图形应用程序),我得到相同的&#34;没有检测到支持CUDA的设备&#34;错误。

当我关闭自动图形切换时,它会强制Mac使用独立显卡,然后程序按预期运行。

纯粹基于C / CUDA的代码版本似乎不会受到此偏好的影响,无论是否启用自动切换,该代码始终有效。

答案 1 :(得分:4)

使用ClientEntryghc 7.8.3,我发现您的代码按预期工作。我所做的唯一不同的事情是将nvcc V6.5.12命名为hello.c

hello.cu