2012-03-21 163 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;