2012-03-21 5 views
2

Я недавно начал изучать CUDA, и я интегрировал свой CUDA в MS Visual Studio 2010 с помощью Nsight. Я также приобрел книгу «CUDA по примеру», и я просматриваю все примеры и компилирую их. Однако я столкнулся с ошибкой, которую я не понимаю. Программа взята из главы 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, однако заставляет меня embelish конструктор cuComplex для устройства, в противном случае он не будет компилировать (он говорит мне, что я не могу использовать его в дальнейшем в функции JuLiA), который я предполагаю, справедливо. Поэтому у меня есть:

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

Но когда я запустить пример (добавив необходимое включает в себя для того, чтобы запустить через VS, который cuda_runtime.h и device_launch_parameters.h, а также копирование glut32.dll в в той же папке, что и exe), она быстро выходит из строя, убивая моего драйвера устройства и заявляя, что это связано с неизвестной ошибкой в ​​строке 94, которая является вызовом cudaMemcpy в main. Точнее, это фактическая строка, содержащая вызов «cudaDeviceToHost». Однако, чтобы быть откровенным, я попытался создать некоторую точку останова после строки, и драйвер умирает при вызове ядра.

Не могли бы вы рассказать мне, что может быть неправильным? Я ноуб с CUDA и понятия не имею, почему тривиальный пример может убить себя таким образом. Что я могу делать неправильно? Потому что, честно говоря, я даже не знаю, что исследовать. У меня есть набор инструментов CUDA 4.1, NSight 2.1 и GeForce GT445M с вычислительной способностью, равной 2,1 и версии драйверов версии 295.

+0

Вы проверили, используете ли вы цель 2.0 для вычисления в таблице свойств CUDA в Visual C++? –

+0

Нет, и, откровенно говоря, я не вижу такой настройки на страницах свойств проекта в разделе «CUDA C/C++». Где я смотрю? –

+0

В разделе «Устройство> Генерация кода» – Bart

ответ

2

У меня еще не было времени проверить это, но я думаю, что это может быть ваш GFX «тайм-аут» до окна.

Windows имеет поведение по умолчанию из Vista, чтобы сообщить драйверу gfx восстановить его через 2 секунды. Если ваша работа занимает больше времени, вы загружаетесь. Вы можете увеличить или удалить эту функцию через реестр. Я предполагаю, что вам нужна перезагрузка для этого, потому что я только что внес изменения, и он пока не работает. Смотрите эту ссылку для деталей: http://msdn.microsoft.com/en-us/windows/hardware/gg487368.aspx

...

Тайм-аут обнаружения и восстановления: Windows Vista пытается обнаружить эти проблемные вешают ситуации и восстановить отзывчивый рабочий стол динамически. В этом процессе драйвер Windows Display Driver Model (WDDM) повторно инициализируется, и GPU сбрасывается. Не требуется перезагрузка, , что значительно улучшает работу пользователя. Единственным видимым артефактом от обнаружения зависания до восстановления является мерцание экрана, которое является результатом сброса некоторых частей графического стека, вызывая перерисовку экрана . Некоторые старые приложения Microsoft DirectX могут отображать черный экран в конце этого восстановления. Конечный пользователь должен будет перезапустить эти приложения. Ниже приводится краткий обзор процесса TDR: ....

Очевидно, именно поэтому его странная ошибка, потому что это даст вам, что мем ошибка копирования в различных масштабах для разных людей, в зависимости от того, как быстро их gfx есть.

Это известная проблема в CUDA.

+0

Это оказалось правдой. Отказавшись от этого, я продолжил отлаживать еще немного на следующий день, и проблема разрешилась сама. Люди должны быть хорошо осведомлены об этой проблеме. –

0

Вы можете попробовать: const float scale = 1.5;

что-то большее, как 3.5, 4.5, 5.5.

пример: const float scale = 5.5;