c++ - tutorial - when to use cuda
Ausgabe von Cuda-Programm ist nicht was erwartet wurde (2)
Das Hauptproblem mit Ihrem Code besteht darin, dass Sie keinen Gerätespeicher für den Aufruf setValues zuweisen. Sie können nicht einen Zeiger auf Host-Speicher übergeben (char * x [6]) und erwarten, dass dies funktioniert; Die CUDA-Kernel müssen mit CUDA-Speicher arbeiten. Sie erstellen diesen Speicher, bearbeiten ihn und kopieren ihn dann zurück:
#include <stdio.h>
#include <string.h>
#include <cuda.h>
#include <cuda_runtime.h>
__global__ void setValues(char *arr){
arr[blockIdx.y * gridDim.x + blockIdx.x] = '4';
}
int main() {
const int NCHARS=6;
char *xd;
cudaMalloc(&xd, NCHARS);
dim3 grid(3,2);
setValues<<<grid,1>>>(xd);
char *p;
p = (char*) malloc(20*sizeof(char));
strcpy(p,"");
cudaMemcpy(p, xd, NCHARS, cudaMemcpyDeviceToHost);
p[NCHARS]='\0';
printf("<%s>\n", p);
getchar();
cudaFree(xd);
return 0;
}
#include<cuda_runtime.h>
#include<stdio.h>
#include<cuda.h>
#include<stdlib.h>
__global__ void setVal(char **c){
c[(blockIdx.y * gridDim.x) + blockIdx.x] = "hello\0";
}
int main(){
char **gpu = NULL;
cudaMalloc((void**)&gpu, 6 * sizeof(char *));
int i;
/*
I cannot access second level directly
for( i =0 ; i < 6 ;i++){
cudaMalloc((void**)&gpu[i], 10 * sizeof(char));
}*/
dim3 grid(3,2);
setVal<<<grid, 1>>>(gpu);
char *p = (char*)malloc(10 * sizeof(char));
char *x[6];
cudaMemcpy(x, gpu, 6*sizeof(char*), cudaMemcpyDeviceToHost);
for( i =0 ; i< 6; i++){
cudaMemcpy(p, x[i], 10*sizeof(char), cudaMemcpyDeviceToHost);
//put synchronize here if problem
printf("%s\n",p);
}
getchar();
return 0;
}
Basierend auf all den Vorschlägen habe ich meinen Code überarbeitet, um mein Konzept zu korrigieren. Aber, der Code funktioniert immer noch nicht :(. Jede Hilfe wird geschätzt
Es gibt einige Probleme, die ich hier sehe. Hier sind einige der offensichtlichsten:
Erstens, meine Annahme ist, dass die Zeichenkettenkonstante "4" im Host-Speicher (CPU) gespeichert ist, so dass Sie sie explizit in den (globalen) Speicher des Geräts kopieren müssten. Sobald die Zeichenfolge "4" im Gerätespeicher vorhanden ist, können Sie einen Zeiger auf "4" in einem Gerätespeicherwert speichern, z. B. ein Element von array arr
.
Zweitens, das Array x
Sie an den setValues
Kernel übergeben, befindet sich ebenfalls im Host-Speicher. Denken Sie daran, dass Sie cudaMalloc
verwenden cudaMalloc
, um einen (globalen) Gerätespeicherbereich zuzuordnen, auf den dann ein Geräte-Kernel zeigen kann.