基本示例中的cudaMemcpyDeviceToHost错误

时间:2012-03-21 15:28:47

标签: cuda

我最近开始学习CUDA,并且已经使用Nsight将我的CUDA集成到MS Visual Studio 2010中。我还获得了“CUDA by example”这本书,我将通过所有的例子并编译它们。然而,我遇到了一个错误,我不明白。 该程序来自第4章,它是julia_gpu的例子。原始代码:

#include "../common/book.h"
#include "../common/cpu_bitmap.h"

#define DIM 1000

struct cuComplex {
    float   r;
    float   i;
    cuComplex( float a, float b ) : r(a), i(b)  {}
    __device__ float magnitude2( void ) {
        return r * r + i * i;
    }
    __device__ cuComplex operator*(const cuComplex& a) {
        return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
    }
    __device__ cuComplex operator+(const cuComplex& a) {
        return cuComplex(r+a.r, i+a.i);
    }
};

__device__ int julia( int x, int y ) {
    const float scale = 1.5;
    float jx = scale * (float)(DIM/2 - x)/(DIM/2);
    float jy = scale * (float)(DIM/2 - y)/(DIM/2);

    cuComplex c(-0.8, 0.156);
    cuComplex a(jx, jy);

    int i = 0;
    for (i=0; i<200; i++) {
        a = a * a + c;
        if (a.magnitude2() > 1000)
            return 0;
    }

    return 1;
}

__global__ void kernel( unsigned char *ptr ) {
    // map from blockIdx to pixel position
    int x = blockIdx.x;
    int y = blockIdx.y;
    int offset = x + y * gridDim.x;

    // now calculate the value at that position
    int juliaValue = julia( x, y );
    ptr[offset*4 + 0] = 255 * juliaValue;
    ptr[offset*4 + 1] = 0;
    ptr[offset*4 + 2] = 0;
    ptr[offset*4 + 3] = 255;
}

// globals needed by the update routine
struct DataBlock {
    unsigned char   *dev_bitmap;
};

int main( void ) {
    DataBlock   data;
    CPUBitmap bitmap( DIM, DIM, &data );
    unsigned char    *dev_bitmap;

    HANDLE_ERROR( cudaMalloc( (void**)&dev_bitmap, bitmap.image_size() ) );
    data.dev_bitmap = dev_bitmap;

    dim3    grid(DIM,DIM);
    kernel<<<grid,1>>>( dev_bitmap );

    HANDLE_ERROR( cudaMemcpy( bitmap.get_ptr(), dev_bitmap,
                              bitmap.image_size(),
                              cudaMemcpyDeviceToHost ) );

    HANDLE_ERROR( cudaFree( dev_bitmap ) );

    bitmap.display_and_exit();
}

我的Visual Studio强迫我将cuComplex构造函数强制为 device ,否则它将无法编译(它告诉我以后不能在julia函数中使用它),我认为这是公平的足够。所以我有:

__device__ cuComplex( float a, float b ) : r(a), i(b)  {}

但是当我运行这个例子时(已经添加了必要的包含它来运行VS,这是cuda_runtime.h和device_launch_parameters.h,以及将glut32.dll复制到与exe相同的文件夹中)它快速失败,杀死我的设备驱动程序并说这是由于第94行中的未知错误,这是主要的cudaMemcpy调用。确切地说,它是包含调用“cudaDeviceToHost”的实际行。坦率地说,我已尝试逐行创建一些断点,并且驱动程序在内核调用时死亡。

有人可以告诉我可能有什么问题吗?我是CUDA的菜鸟,并且不知道为什么一个简单的例子会像这样自杀。我能做错什么?坦率地说,我甚至不知道该调查什么。 我有CUDA 4.1工具包,NSight 2.1和GeForce GT445M,计算能力分别为2.1和295版本的驱动程序。

2 个答案:

答案 0 :(得分:2)

我还没来得及测试这个,但我认为就Windows而言,它可能是你的GFX“超时”。

Windows具有Vista的默认行为,告诉gfx驱动程序在2秒后恢复。如果你的工作需要更长时间,那么你就会被启动。您可以通过注册表增加或删除此功能。我假设您需要重新启动,因为我刚刚进行了更改,但它还没有运行。 有关详细信息,请参阅此链 http://msdn.microsoft.com/en-us/windows/hardware/gg487368.aspx

...

  

超时检测和恢复:Windows Vista尝试检测这些   有问题的挂起情况并恢复响应式桌面   动态。在此过程中,Windows显示驱动程序模型(WDDM)   驱动程序重新初始化并重置GPU。无需重启,   这极大地增强了用户体验。唯一可见的神器   从挂起检测到恢复是屏幕闪烁,其中   重置图形堆栈的某些部分导致a   屏幕重绘。某些较旧的Microsoft DirectX应用程序可能会呈现给   在这次恢复结束时出现黑屏。最终用户必须   重启这些应用程序以下是对该的简要概述   TDR流程:....

显然,这就是为什么它是一个奇怪的错误,因为它会根据gfx的速度为不同的人提供不同比例的mem copy错误。

这是CUDA中的一个已知问题。

答案 1 :(得分:0)

您可以尝试更改此内容: const float scale = 1.5;

更大的东西,如3.5,4.5,5.5。

例如: const float scale = 5.5;