Программа CUDA, дающая значение мусора - PullRequest
0 голосов
/ 15 августа 2011

Я действительно не понимаю, почему вывод для кода ниже не a и b.

#include<cutil.h>
#include<iostream>
__global__ void p(unsigned char **a){


unsigned char temp[2];
temp[0] = 'a';
temp[1] = 'b';
a[0] = temp;


}

void main(){

    unsigned char **a ;
    cudaMalloc((void**)&a, sizeof(unsigned char*));
    p<<<1,1>>>(a);
    unsigned char **c;
    unsigned char b[2];
    cudaMemcpy(c, a, sizeof(unsigned char *), cudaMemcpyDeviceToHost);
    cudaMemcpy(b, c[0], 2*sizeof(unsigned char), cudaMemcpyDeviceToHost);
    for( int i=0 ; i < 2; i++){
        printf("%c\n", b[i]);
    }


    getchar();


}

что не так с моей логикой?

1 Ответ

1 голос
/ 15 августа 2011

Давай пока оставим CUDA. Давайте просто сделаем функцию, которая записывает данные в предоставленный пользователем массив. Пользователь передает массив через указатель:

void fill_me_up(int * dst)
{
  // We sure hope that `dst` points to a large enough area of memory!

  dst[0] = 28;
  dst[1] = 75;
}

Теперь то, что вы делаете с локальной переменной, не имеет смысла, потому что вы хотите использовать адрес локальной переменной, который становится недействительным после выхода из области действия функции. Следующее лучшее, что вы можете сделать, это memcpy(), или какой-то эквивалентный алгоритм C ++:

void fill_me_up_again(int * dst)
{
  int temp[] = { 28, 75 };
  memcpy((void *)dst, (const void *)temp, sizeof(temp));
}

Хорошо, теперь вызовите эту функцию: сначала мы должны предоставить целевую память, а затем передать указатель:

int main()
{
  int my_memory[2]; // here's our memory -- automatic local storage

  fill_me_up(my_memory);     // OK, array decays to pointer-to-beginning
  fill_me_up(&my_memory[0]); // A bit more explicit

  int * your_memory = malloc(sizeof(int) * 2); // more memory, this time dynamic
  fill_me_up_again(your_memory);
  /* ... */
  free(your_memory);
}

(В C ++ вы, вероятно, могли бы использовать new int[2] и delete your_memory вместо этого, но, используя C malloc(), мы надеемся, что соединение с CUDA станет ясным.)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...