EmuDebug VS Release

Пытаюсь собрать простейший проект с использованием CUDA, в режиме эмуляции всё работает отлично, но как только собираю Release - не получается передать значения из ядра в host.

Вот пример кода:

  1. #define THREADS_PER_BLOCK 64
  2.  
  3. typedef unsigned long long long64;
  4. typedef unsigned char u8;
  5. typedef unsigned long u32;
  6.  
  7. #pragma pack(push, 1)
  8. struct __align__(16) fake_u64
  9. {
  10.  u32 hi;
  11.  u32 lo;
  12. };
  13. #pragma pack(pop)
  14.  
  15. typedef fake_u64 u64;
  16.  
  17. __global__ void CUDA_unit(u64 *shedule, u64 *d_result)
  18. {
  19.  u32 idx = blockIdx.x*blockDim.x + threadIdx.x;
  20.  
  21.  if (idx == 0) {
  22.    d_result->hi = 1;
  23.    d_result->lo = 2;
  24.  }
  25.  return;
  26. }
  27.  
  28. int main(void)
  29. {
  30.  u64  *d_result;
  31.  u64  *h_result;
  32.  u64  *d_shedule;
  33.  u64  *h_shedule;
  34.  u64  in;
  35.  
  36.  CUT_DEVICE_INIT(NULL, NULL);
  37.  
  38.  in.hi = 1;
  39.  in.lo = 2;
  40.  shedule_size = 2;
  41.  
  42.  h_shedule = (u64 *)malloc(sizeof(u64)*shedule_size);
  43.  if (!h_shedule) {
  44.    printf("No memory on host for shedule array\n");
  45.    return 0;
  46.  }
  47.  
  48.  h_result = (u64 *)malloc(sizeof(u64));
  49.  if (!h_result) {
  50.    printf("No memory on host for result\n");
  51.    return 0;
  52.  }
  53.  
  54.  h_result->hi = 0;
  55.  h_result->lo = 0;
  56.  
  57.  CUDA_SAFE_CALL( cudaMalloc((void**) &d_result, sizeof(u64)) );
  58.  CUDA_SAFE_CALL( cudaMemcpy(d_result, h_result, sizeof(u64), cudaMemcpyHostToDevice) );
  59.  
  60.  for (i=0; i<shedule_size; i++) {
  61.    h_shedule[i] = in;
  62.  }
  63.  
  64.  CUDA_SAFE_CALL(cudaMalloc((void **)&d_shedule, shedule_size*sizeof(u64)) );
  65.  cudaMemcpy(d_shedule, h_shedule, shedule_size*sizeof(u64), cudaMemcpyHostToDevice);
  66.  free(h_shedule);
  67.  
  68.  num_blocks = shedule_size / THREADS_PER_BLOCK + (shedule_size % THREADS_PER_BLOCK == 0 ? 0 : 1);
  69.  
  70.  CUDA_unit<<<num_blocks, shedule_size>>>(d_shedule, (u64 *)d_result);
  71.  
  72.  CUDA_SAFE_CALL( cudaThreadSynchronize() );
  73.  
  74.  CUT_CHECK_ERROR("CUDA_unit");
  75.  
  76.  CUDA_SAFE_CALL( cudaMemcpy(h_result, d_result, sizeof(u64), cudaMemcpyDeviceToHost) );
  77.  
  78.  printf ("%08X:%08X\n", h_result->hi, h_result->lo);
  79.  
  80.  CUDA_SAFE_CALL( cudaFree(d_result) );
  81.  CUDA_SAFE_CALL( cudaFree(d_shedule) )
  82.  
  83.  free(h_result);
  84.  
  85.  CUT_EXIT(NULL, NULL);
  86. }

здесь значение h_result должен вернуть только один - первый тред, поэтому никаких проблем с доступом к памяти возникнуть не должно, но у меня почему-то h_result всегда равен 0 в Release версии.
При отладке в эмуляторе все значения передаются как нужно. Что я делаю не так?

P.S. Использую VC2005, CUDA 2.0

Forums: 

Под эмулятором при отладке я

Под эмулятором при отладке я подразумеваю режим компиляции с ключем -deviceemu, в Release собираю без этого ключа, с отключенной оптимизацией, но запускаю на машине без видеокарты NVidia, при этом используется CPU("Using device 0: Device Emulation (CPU)").

вообще не удивительно, что

вообще не удивительно, что ничего не возвращалось, т.к. ядро CUDA не работает CPU.
теперь столкнулся с другой проблемой - результаты расчетом в эмуляторе и на железе не сходятся.

Это нормально, об этом можно

Это нормально, об этом можно почитать на сайте nVidia. Также напомню, что результаты на процессоре с одними и теме же данными, но в разных потоках тоже будут разными (поднобнее на сайте Intel).

спасибо, форум nvidia уже

спасибо, форум nvidia уже помог мне решить все проблемы.
было бы замечательно если бы админы стерли эту тему, т.к. вопрос в ней задан не корректно.

тогда опишу здесь свои

тогда опишу здесь свои грабли, чтобы на них больше никто не наступал :)

1. проверка ошибок( CUT_CHECK_ERROR) работает только в Debug сборке, во всех остальных треды молча запустятся, очень быстро "отработают", но на самом деле ничего не выполнится. Чаще всего такое бывает при большом количестве регистров в блоке, большом количестве shared memory.
2. сдвиг работает по другому
3. может возникнуть такая ситуация, что вы не объявили переменную, которую хотите использовать из GPU, как __device__, в эмуляторе всё будет отлично, в железе - нет.