2011-07-03 31 views
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; 
} 

根据所有建议,我修改了我的代码以使我的概念正确无误。但是,代码仍然没有工作:(任何帮助将不胜感激cuda程序的输出结果不是预期的

+0

当我添加一个手表网格,它说网格没有找到。 – Programmer

+0

任何人都可以使用cuda机器为我运行并检查? – Programmer

+0

你甚至没有问题了。 – tkerwin

回答

3

试试这个 - 我测试了它在GTX 285 CUDA 3.2下 - 所以这是一个有点比目前的版本更加严格,但有用。

#include<stdio.h> 
#include<string.h> 

__global__ void setValues(char** word) 
{ 
    volatile char* myWord = word[blockIdx.x]; 

    myWord[0] = 'H'; 
    myWord[1] = 'o'; 
    myWord[2] = 'l'; 
    myWord[3] = 'a'; 
    myWord[4] = '\0'; 
} 

int main() 
{ 
    const size_t bufferSize = 32; 
    const int nObjects = 10; 

    char* h_x[nObjects]; 
    char** d_x = 0; 

    cudaMalloc((void**)(&d_x), nObjects * sizeof(char*)); 

    for (int i=0; i < nObjects; i++) 
    { 
     h_x[i] = NULL; 
     cudaMalloc((void**)(&h_x[i]), bufferSize * sizeof(char)); 
     printf("h_x[%d] = %lx\n",i,(unsigned long)h_x[i]); 
    } 

    cudaMemcpy(d_x, h_x, nObjects*sizeof(char*), cudaMemcpyHostToDevice); 
    printf("Copied h_x[] to d_x[]\n"); 

    char msg[] = "Hello World!"; 
    cudaMemcpy(h_x[0], msg, 13*sizeof(char), cudaMemcpyHostToDevice); 

    /* Force Thread Synchronization */ 
    cudaError err = cudaThreadSynchronize(); 

    /* Check for and display Error */ 
    if (cudaSuccess != err) 
    { 
     fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", 
       __FILE__, __LINE__, cudaGetErrorString(err)); 
    } 

    setValues<<<nObjects,1>>>(d_x); 

    /* Force Thread Synchronization */ 
    err = cudaThreadSynchronize(); 

    /* Check for and display Error */ 
    if (cudaSuccess != err) 
    { 
     fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", 
       __FILE__, __LINE__, cudaGetErrorString(err)); 
    } 

    printf("Kernel Completed Successfully. Woot.\n\n"); 

    char p[bufferSize]; 

    printf("d_x = %lx\n", (unsigned long)d_x); 
    printf("h_x = %lx\n", (unsigned long)h_x); 

    cudaMemcpy(h_x, d_x, nObjects*sizeof(char*), cudaMemcpyDeviceToHost); 

    printf("d_x = %lx\n", (unsigned long)d_x); 
    printf("h_x = %lx\n", (unsigned long)h_x); 

    for (int i=0; i < nObjects; i++) 
    { 
     cudaMemcpy(&p, h_x[i], bufferSize*sizeof(char), cudaMemcpyDeviceToHost); 
     printf("%d p[] = %s\n",i,p); 
    } 

    /* Force Thread Synchronization */ 
    err = cudaThreadSynchronize(); 

    /* Check for and display Error */ 
    if (cudaSuccess != err) 
    { 
     fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n", 
       __FILE__, __LINE__, cudaGetErrorString(err)); 
    } 

    getchar(); 

    return 0; 
} 

正如@乔恩笔记,你不能将X(因为你已经声明)它的GPU,因为它是该生活在CPU上的地址。在上面的代码中,我创建了一个char *的数组,并将它们传递给我也在GPU上分配的char **。希望这可以帮助!

+0

char **是什么意思?请举个例子吗? – Programmer

+0

它是一个指向数组的指针。 –

+0

这里有一个非常棒的页面(http://www.cplusplus.com/doc/tutorial/pointers/),它描述了指向**底部的指针**的指针。注意:它甚至在其示例中使用'char **'。 –

1

有我在这里看到的一些问题下面是一些最明显的的:。

首先,我的猜测是,字符串常量“4”存储在主机(CPU)存储器中,因此您必须将其明确复制到设备(全局)存储器。一旦字符串“4”位于设备存储器中,然后您可以将指针“4”中的一个设备内存值,比如一个元素的数组arr

二,将你传给的数组内核是也在主机内存中。请记住,您需要使用cudaMalloc来分配设备内核可以指向的(全局)设备内存区域。

2

您的代码的主要问题是您没有为setValues调用分配任何设备内存。你不能将它传递给主机内存的指针(char * x [6]),并期望它工作; CUDA内核必须在CUDA内存上运行。您创建的内存,然后在其上进行操作,然后将它复制回:

#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; 
} 
+1

注意:char * xd是一个指向char数组的指针。我需要一个char指针数组,因为我想初始化一个字符串给数组的每个索引。你能改变你的代码来适应这个吗? – Programmer