【问题标题】:Passing char array to CUDA Kernel将 char 数组传递给 CUDA 内核
【发布时间】:2014-09-24 07:49:12
【问题描述】:

我正在尝试将从主函数中的 txt 文件读取的包含 10000 个单词的 char 数组传递给 CUDA 内核函数。

单词从主机传输到设备是这样的:

(主要功能代码:)

//.....
     const int text_length = 20;

     char (*wordList)[text_length] = new char[10000][text_length];
     char *dev_wordList;

     for(int i=0; i<number_of_words; i++)
     {
         file>>wordList[i];
         cout<<wordList[i]<<endl;
     }

     cudaMalloc((void**)&dev_wordList, 20*number_of_words*sizeof(char));
     cudaMemcpy(dev_wordList, &(wordList[0][0]), 20 * number_of_words * sizeof(char), cudaMemcpyHostToDevice);

    //Setup execution parameters
    int n_blocks = (number_of_words + 255)/256;
    int threads_per_block = 256;


    dim3 grid(n_blocks, 1, 1);
    dim3 threads(threads_per_block, 1, 1);


    cudaPrintfInit();
    testKernel<<<grid, threads>>>(dev_wordList);
    cudaDeviceSynchronize();
    cudaPrintfDisplay(stdout,true);
    cudaPrintfEnd();

(内核功能代码:)

__global__ void testKernel(char* d_wordList)
{
    //access thread id
    const unsigned int bid = blockIdx.x;
    const unsigned int tid = threadIdx.x;
    const unsigned int index = bid * blockDim.x + tid;

    cuPrintf("!! %c%c%c%c%c%c%c%c%c%c \n" , d_wordList[index * 20 + 0],
                                            d_wordList[index * 20 + 1],
                                            d_wordList[index * 20 + 2],
                                            d_wordList[index * 20 + 3],
                                            d_wordList[index * 20 + 4],
                                            d_wordList[index * 20 + 5],
                                            d_wordList[index * 20 + 6],
                                            d_wordList[index * 20 + 7],
                                            d_wordList[index * 20 + 8],
                                            d_wordList[index * 20 + 9]);
}

有没有办法更容易地操纵它们? (我希望每个元素/位置都有一个单词)我尝试使用 &lt;string&gt;,但我无法在 CUDA 设备代码中使用它们。

【问题讨论】:

    标签: c++ c cuda arrays


    【解决方案1】:
    cuPrintf("%s\n", d_wordlist+(index*20));
    

    应该有效吗? (前提是你的字符串是以零结尾的)

    更新:

    这一行:

    char (*wordList)[text_length] = new char[10000][text_length];
    

    对我来说看起来很奇怪。一般来说,指向 char 的指针数组会像这样分配:

    char** wordList = new char*[10000];
    for (int i=0;i<10000;i++) wordList[i] = new char[20];
    

    在这种情况下,wordList[i] 将是指向字符串编号 i 的指针。

    更新 #2:

    如果您需要将字符串存储为连续块,并且您确定没有任何字符串超过 text_length+1,那么您可以这样做:

    char *wordList = new char[10000*text_length];
    
    for(int i=0; i<number_of_words; i++)
         {
             file>>wordList+(i*text_length);
             cout<<wordList+(i*text_length)<<endl;
         }
    

    在这种情况下,wordList + (i*text_length) 将指向字符串编号 i 的开头,并且它将以 0 结尾,因为这是您从文件中读取它的方式,并且您将能够打印它以this answer中指定的方式退出。但是,如果您的任何字符串长于 text_length-1,您仍然会遇到问题。

    【讨论】:

    • 我试过了,但我得到了一系列奇怪的字符。
    • 在代码中复制字符串的方式,看起来它们不是以零结尾的(您为每个字符串分配 20 个符号并执行 memcpy i/o strcpy)。是否可以为每个字符串分配 21 个符号并在每个字符串后添加 '\0'?
    • 是的,但我不知道该怎么做。如果终止符在每个字符串之后会更好。
    • 你所有的词都是20个符号还是你估计是这样的?
    • 字符串从主机到设备的传输是正确的,问题出在 cuPrintf 调用上,我试图输出一个在内核函数中声明的字符串,它只输出声明为 const char 的字符串*。所以我将内核函数参数声明从 global void testKernel(char* d_wordList) 修改为 global void testKernel(const char* d_wordList) 现在有用。非常感谢!
    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    相关资源
    最近更新 更多