#cuda
Вопрос:
Я получаю ошибку сегментации (сброс ядра) при запуске этого кода.
Я знаю, что проблема в cudaMalloc, но я понятия не имею, как ее решить. Я только начал изучать программирование на CUDA и не знаком с ним. Я работаю над wsl, если это имеет значение.
#include<stdio.h>
#define SIZE 20
__global__ void VectorAdd(int *a,int *b,int *c,int n){
int i = threadIdx.x;
if(i<n)
c[i]=a[i] b[i];
}
int main(){
int *a,*b,*c;
cudaMalloc((void**)amp;a,SIZE *sizeof(int));
cudaMalloc((void**)amp;b, SIZE *sizeof(int));
cudaMalloc((void**)amp;c,SIZE *sizeof(int));
for (int i=1;i<SIZE;i ){
a[i]=i;
b[i]=i;
c[i]=0;
}
VectorAdd<<<1, SIZE>>>(a,b,c,SIZE);
cudaDeviceSynchronize();
for(int i=1;i<SIZE;i ){
printf("%d n",c[i]);
}
cudaFree(a);
cudaFree(b);
cudaFree(c);
return 0;
}
Комментарии:
1. На распределение, созданное с использованием
cudaMalloc
, нельзя напрямую ссылаться из кода хоста, как вы пытаетесь сделать здесь:a[i]=i;
. Существует пример кода CUDA, который называетсяvectorAdd
и дает типичный способ справиться с этим. Вы смотрели этот пример кода?2. Опубликованный код также не смог бы распечатать
c[]
значения в конце.3. Если вы хотите использовать обычный код, чтобы инициализировать свои массивы, и обычный код, чтобы напечатать сумму обратно (как вы пытаетесь здесь), вы будете иметь, чтобы: (А) как выделить оперативную память и CUDA памяти (для регулярного памяти можно использовать простые массивы, либо позвонить
malloc
); (б) инициализировать хост массивов (с) копирование с хоста на устройство, используяcudaMemcpy
, (д) обратитесь к ядру, чтобы сделать дополнение, (Эл.) копировать с устройства памяти в хост-память черезcudaMemcpy
раз, и, наконец, (е) распечатывает результат.4. Спасибо вам за ваши ответы. Я изучу пример кода.
Ответ №1:
Как уже предлагалось в комментариях, вам необходимо инициализировать значения для массивов a
и b
на хосте, скопировать их в массив устройств, а после завершения вычисления вам необходимо скопировать данные c
обратно на хост.
#include<stdio.h>
#define SIZE 20
__global__ void VectorAdd(int *a,int *b,int *c,int n){
int i = threadIdx.x;
if(i<n)
c[i]=a[i] b[i];
}
int main(){
int *a,*b,*c;
int *h_a, *h_b, *h_c; /*declare pointers to host arrays*/
cudaMalloc((void**)amp;a,SIZE *sizeof(int));
cudaMalloc((void**)amp;b, SIZE *sizeof(int));
cudaMalloc((void**)amp;c,SIZE *sizeof(int));
/* allocate memory for host arrays */
h_a = new int[SIZE];
h_b = new int[SIZE];
h_c = new int[SIZE];
/* initialize values on host arrays */
for (int i = 0; i < SIZE; i ){
h_a[i]=i;
h_b[i]=i;
}
/*copy data from host to device */
cudaMemcpy(a, h_a, SIZE*sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(b, h_b, SIZE*sizeof(int), cudaMemcpyHostToDevice);
VectorAdd<<<1, SIZE>>>(a,b,c,SIZE);
// cudaDeviceSynchronize(); /* this is not needed because cudaMemcpy implies sync. */
/*copy results from device to host*/
cudaMemcpy(h_c, c, SIZE*sizeof(int), cudaMemcpyDeviceToHost);
for(int i = 0; i < SIZE; i ){
printf("%d n",h_c[i]);
}
cudaFree(a);
cudaFree(b);
cudaFree(c);
/* free host memory */
delete [] h_a;
delete [] h_b;
delete [] h_c;
return 0;
}
Примечания
- По какой-то причине вы начинаете итерацию с позиции
1
, а0
не в вас для циклов! Если это случайно неправильно, я это исправил! cudaMemcpy
всегда выполняет синхронизацию между хостом и устройством. Таким образом,cudaDeviceSynchronize()
нет необходимости после вызова ядра.- Чтобы избежать явной обработки отдельных данных хоста и устройства, вы можете использовать
cudaMallocManaged
вместоcudaMalloc
.