2012-03-21 40 views
2

我最近开始学习CUDA,并且我已将NUD中的CUDA集成到MS Visual Studio 2010中。我还收购了“CUDA by Example”一书,我正在浏览所有示例并编译它们。我遇到了一个错误,但我不明白。该程序来自第4章,它是julia_gpu示例。原代码:基本示例中的cudaMemcpyDeviceToHost错误

#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构造embelish到设备,否则将无法编译(它告诉我,我不能用它后来在茱莉亚功能),我猜是够公平的。所以,我有:

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

但是当我做运行示例(已添加了必要的包括其通过VS,这是cuda_runtime.h和device_launch_parameters.h,以及复制要将glut32.dll到运行与exe文件夹相同的文件夹),它很快就会失败,导致我的设备驱动程序失效,并说这是由于第94行的一个未知错误造成的,这是main中的cudaMemcpy调用。确切地说,它是包含调用“cudaDeviceToHost”的实际行。坦率地说,我试图在线后创建一些断点,并且驱动程序在内核调用时死亡。

有人能告诉我什么可能是错的吗?我是CUDA的noob,并没有真正的想法,为什么一个微不足道的例子会这样自杀。我可能做错了什么?坦率地说,我真的不知道要调查什么。 我有CUDA 4.1工具包,NSight 2.1和GeForce GT445M,计算能力为2.1和295版本的驱动程序。

+0

您是否检查过在Visual C++的CUDA属性表中使用了计算能力2.0目标? – 2012-03-21 16:10:07

+0

不,坦率地说,我没有在我的项目属性页下的“CUDA C/C++”部分看到这样的设置。我在哪里看? – 2012-03-21 16:33:12

+0

在“设备>代码生成”下面 – Bart 2012-03-21 18:36:26

回答

2

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

Windows从Vista有一个默认行为,告诉gfx驱动程序在2秒后恢复。如果你的工作需要更长的时间,那么你可以启动。您可以通过注册表来增加或删除此功能。我认为你需要重新启动,因为我只是做了改变,它还没有工作。 请参阅此链接查看详细: http://msdn.microsoft.com/en-us/windows/hardware/gg487368.aspx

...

超时检测和恢复:Windows Vista中尝试检测这些 问题的挂起情况和恢复响应的桌面 动态。在此过程中,Windows显示驱动程序模型(WDDM) 驱动程序被重新初始化并且GPU被重置。不需要重新启动, 大大增强了用户体验。从挂起检测到恢复的唯一可见工件 是一个屏幕闪烁,其中 是由于重置图形堆栈的某些部分而导致的,导致屏幕重新绘制 。一些较早的Microsoft DirectX应用程序可能会在此恢复结束时呈现 黑屏。最终用户将不得不 重新启动这些应用程序。以下是 TDR过程的简要概述:....

显然,这就是为什么它的一个奇怪的错误,因为它会给你的MEM在对不同的人不同的比例复制错误取决于如何快速的gfx是。

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

+0

事实证明这是事实。放弃之后,我继续在第二天进行调试,问题已经解决。人们应该清楚地意识到这个问题。 – 2012-05-29 17:16:20

0

你可以尝试改变它: const float scale = 1.5;

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

示例: const float scale = 5.5;