如何将字符串矩阵从C++; 问题: < > C++中有一个字符串,我想把它传递给CUDA内核函数。我知道CUDA不能处理字符串,所以经过一些研究,我尝试了下面列出的一些解决方案 尝试: >P>定义C++中包含指针的数组,每个单元都包含一个指针字符(简单地说,TMP[i]中包含了前面引用的矩阵中包含的字符串)
C++部分如何将字符串矩阵从C++; 问题: < > C++中有一个字符串,我想把它传递给CUDA内核函数。我知道CUDA不能处理字符串,所以经过一些研究,我尝试了下面列出的一些解决方案 尝试: >P>定义C++中包含指针的数组,每个单元都包含一个指针字符(简单地说,TMP[i]中包含了前面引用的矩阵中包含的字符串),c++,cuda,gpu,C++,Cuda,Gpu,C++部分 将填充有字符串的矩阵分散到一个char指针,并将其传递给cuda内核,然后在那里尝试检索字符串(同样是用C++简化的代码) C++部分 我尝试过很多其他的解决方案,但是没有人适合我。。。这个问题也可以重新提出:我如何将'n'字符串传递给cuda内核,并在那里打印(和比较)所有这些字符串(请记住,我不能传递'n'变量)。您所展示的其他代码都已完成,您遗漏的内容可能很重要。如果您显示完整的代码,您将使其他人更容易帮助您。此外,无论何时,当你在与CUDA代码斗争时,使用这些代码都是一种
我尝试过很多其他的解决方案,但是没有人适合我。。。这个问题也可以重新提出:我如何将'n'字符串传递给cuda内核,并在那里打印(和比较)所有这些字符串(请记住,我不能传递'n'变量)。您所展示的其他代码都已完成,您遗漏的内容可能很重要。如果您显示完整的代码,您将使其他人更容易帮助您。此外,无论何时,当你在与CUDA代码斗争时,使用这些代码都是一种很好的做法,通常会指出哪些代码不起作用(我怀疑这可能会对你的第二次尝试有所帮助)。此外,使用
cuda memcheck
运行代码通常是很有启发性的
在第一次尝试中,您遇到了CUDA和嵌套指针的典型问题(a
是指向指针数组的指针)。几乎在任何时候,只要有一个指针埋在其他数据结构中,这个问题就会发生。要将这样的数据结构从主机复制到设备,需要一个“深度复制”操作,该操作有多个步骤。为了进一步了解这一点,搜索“CUDA 2D数组”(我认为标准答案是Talon),或者看看我的答案。p>
另外请注意,如果您能够使用CUDA6,“深度拷贝”在概念上对程序员来说会容易得多
您的第二次尝试似乎是沿着“展平”2D或指向char
的ponter数组的指针的路径前进。这是深度复制“问题”的典型解决方案,可以降低代码复杂度,并可能提高性能。下面是一个充分发挥作用的示例,将您第一次和第二次尝试的想法融合在一起,这似乎对我很有用:
$ cat t389.cu
#include <stdio.h>
__global__ void func(char* a, int *indexes, int num_strings){
for(int i=0;i<num_strings;i++){
printf("string[%d]: ", i);
for (int j=indexes[2*i]; j < indexes[2*i+1]; j++)
printf("%c", a[j]);
printf("\n");
}
}
int main(){
int max_text_length, num_str;
num_str = 3;
char *tmp[num_str];
max_text_length = 12;
tmp[0] = (char*) malloc(max_text_length*sizeof(char));
tmp[1] = (char*) malloc(max_text_length*sizeof(char));
tmp[2] = (char*) malloc(max_text_length*sizeof(char));
tmp[0] = "some text";
tmp[1] = "rand txt";
tmp[2] = "text";
int stridx[2*num_str];
int *d_stridx;
stridx[0] = 0;
stridx[1] = 9;
stridx[2] = 9;
stridx[3] = 17;
stridx[4] = 17;
stridx[5] = 21;
char *a, *d_a;
a = (char *)malloc(num_str*max_text_length*sizeof(char));
//flatten
int subidx = 0;
for(int i=0;i<num_str;i++)
{
for (int j=stridx[2*i]; j<stridx[2*i+1]; j++)
a[j] = tmp[i][subidx++];
subidx = 0;
}
cudaMalloc((void**)&d_a,num_str*max_text_length*sizeof(char));
cudaMemcpy(d_a, a,num_str*max_text_length*sizeof(char),cudaMemcpyHostToDevice);
cudaMalloc((void**)&d_stridx,num_str*2*sizeof(int));
cudaMemcpy(d_stridx, stridx,2*num_str*sizeof(int),cudaMemcpyHostToDevice);
func<<<1,1>>>(d_a, d_stridx, num_str);
cudaDeviceSynchronize();
}
$ nvcc -arch=sm_20 -o t389 t389.cu
$ cuda-memcheck ./t389
========= CUDA-MEMCHECK
string[0]: some text
string[1]: rand txt
string[2]: text
========= ERROR SUMMARY: 0 errors
$
$cat t389.cu
#包括
__全局函数(char*a,int*索引,int num\u字符串){
对于(int i=0;i您显示的代码中的其他代码是完整的,并且您遗漏的内容可能很重要。如果您显示完整的代码,您将使其他人更容易帮助您。此外,无论何时您在与CUDA代码作斗争,使用这些代码都是一种很好的做法,通常会指出哪些代码不起作用(我怀疑这可能对您的第二次尝试有所帮助)。此外,使用cuda memcheck
运行您的代码通常是有益的
在您的第一次尝试中,您遇到了CUDA和嵌套指针的典型问题(a
是指向指针数组的指针)。几乎在任何时候,当指针埋在其他数据结构中时,都会出现此问题。要将此类数据结构从主机复制到设备,需要“深度复制”操作,它有多个步骤。为了了解更多这一点,搜索“CUDA 2D数组”(我认为正则答案是由滑稽词给出的)或查看我的答案和
另外请注意,如果您能够使用CUDA6,“深度拷贝”在概念上对程序员来说会容易得多
您的第二次尝试似乎是在“展平”2D或指向char
的ponter数组的指针。这是“问题”的典型解决方案深度复制,减少代码复杂度,可能还会提高性能。下面是一个充分发挥作用的示例,融合了您第一次和第二次尝试的想法,对我来说似乎很有效:
$ cat t389.cu
#include <stdio.h>
__global__ void func(char* a, int *indexes, int num_strings){
for(int i=0;i<num_strings;i++){
printf("string[%d]: ", i);
for (int j=indexes[2*i]; j < indexes[2*i+1]; j++)
printf("%c", a[j]);
printf("\n");
}
}
int main(){
int max_text_length, num_str;
num_str = 3;
char *tmp[num_str];
max_text_length = 12;
tmp[0] = (char*) malloc(max_text_length*sizeof(char));
tmp[1] = (char*) malloc(max_text_length*sizeof(char));
tmp[2] = (char*) malloc(max_text_length*sizeof(char));
tmp[0] = "some text";
tmp[1] = "rand txt";
tmp[2] = "text";
int stridx[2*num_str];
int *d_stridx;
stridx[0] = 0;
stridx[1] = 9;
stridx[2] = 9;
stridx[3] = 17;
stridx[4] = 17;
stridx[5] = 21;
char *a, *d_a;
a = (char *)malloc(num_str*max_text_length*sizeof(char));
//flatten
int subidx = 0;
for(int i=0;i<num_str;i++)
{
for (int j=stridx[2*i]; j<stridx[2*i+1]; j++)
a[j] = tmp[i][subidx++];
subidx = 0;
}
cudaMalloc((void**)&d_a,num_str*max_text_length*sizeof(char));
cudaMemcpy(d_a, a,num_str*max_text_length*sizeof(char),cudaMemcpyHostToDevice);
cudaMalloc((void**)&d_stridx,num_str*2*sizeof(int));
cudaMemcpy(d_stridx, stridx,2*num_str*sizeof(int),cudaMemcpyHostToDevice);
func<<<1,1>>>(d_a, d_stridx, num_str);
cudaDeviceSynchronize();
}
$ nvcc -arch=sm_20 -o t389 t389.cu
$ cuda-memcheck ./t389
========= CUDA-MEMCHECK
string[0]: some text
string[1]: rand txt
string[2]: text
========= ERROR SUMMARY: 0 errors
$
$cat t389.cu
#包括
__全局函数(char*a,int*索引,int num\u字符串){
对于(int i=0;ii在您的第一次尝试中,tmp[0]
是指向char
的指针,而不是char
s的数组。另外,为什么要使用cudamaloc((void**)和a,array_length);
?如何分配tmp[0]=“一些”
。总的来说,在我看来,你的想法是使用char
s数组,因此你可能对这篇文章的答案感兴趣。tmp
是char*数组tmp[0]
是char*其中分配了足够的空间来包含“some”。我在处理代码cudamaloc((void**)时出错&a,array_length);
,现在我编辑它。array of array是另一个我尝试过但不起作用的解决方案(对我来说)在CUDA中。谢谢。你所展示的两个代码版本都没有任何意义,而且这些问题与CUDA无关。我认为你需要修改指针、数组和字符串在C++开始之前的工作。在你在GPUI不到任何地方之前,两个版本都会在主机阵列设置代码中进行分段。ink我有一个神奇的编译器,因为这两个代码都没有segfault。这两个版本是解决我的问题的两种不同方法的实现。可能我需要修改指针和字符的工作方式,为此我发布了我的问题。如果你想(并且可以)帮助我,欢迎你。在你的第一次尝试中,tmp[0]
是指向char
的指针,而不是char
s的数组。另外,为什么要使用cudamaloc((void**)和a,数组长度);
?如何分配tmp[0]=“一些”
。总的来说,在我看来,你的想法是使用char
s数组,因此你可能对这篇文章的答案感兴趣。tmp
是char*数组tmp[0]
是char*其中分配了足够的空间来包含“some”。我在处理代码cudamaloc((无效)时出错**
value[0] = (null)
value[1] = (null)
value[2] = (null)
char *a;
int index[6];
a = "somerandtext";
index[0] = 0; // first word start
index[1] = 3; // first word end
index[2] = 4; // same as first word
index[3] = 7;
index[4] = 8;
index[5] = 1;
func<<<blocksPerGrid, threadsPerBlock>>>(a,index);
__global__ void func(char* a,int index[]){
int first_word_start = index[0];
int first_word_end = index[1];
// print first word
for(int i=first_word_start;i<=first_word_end;i++)
printf("%c",a[i]);
}
no output produced
$ cat t389.cu
#include <stdio.h>
__global__ void func(char* a, int *indexes, int num_strings){
for(int i=0;i<num_strings;i++){
printf("string[%d]: ", i);
for (int j=indexes[2*i]; j < indexes[2*i+1]; j++)
printf("%c", a[j]);
printf("\n");
}
}
int main(){
int max_text_length, num_str;
num_str = 3;
char *tmp[num_str];
max_text_length = 12;
tmp[0] = (char*) malloc(max_text_length*sizeof(char));
tmp[1] = (char*) malloc(max_text_length*sizeof(char));
tmp[2] = (char*) malloc(max_text_length*sizeof(char));
tmp[0] = "some text";
tmp[1] = "rand txt";
tmp[2] = "text";
int stridx[2*num_str];
int *d_stridx;
stridx[0] = 0;
stridx[1] = 9;
stridx[2] = 9;
stridx[3] = 17;
stridx[4] = 17;
stridx[5] = 21;
char *a, *d_a;
a = (char *)malloc(num_str*max_text_length*sizeof(char));
//flatten
int subidx = 0;
for(int i=0;i<num_str;i++)
{
for (int j=stridx[2*i]; j<stridx[2*i+1]; j++)
a[j] = tmp[i][subidx++];
subidx = 0;
}
cudaMalloc((void**)&d_a,num_str*max_text_length*sizeof(char));
cudaMemcpy(d_a, a,num_str*max_text_length*sizeof(char),cudaMemcpyHostToDevice);
cudaMalloc((void**)&d_stridx,num_str*2*sizeof(int));
cudaMemcpy(d_stridx, stridx,2*num_str*sizeof(int),cudaMemcpyHostToDevice);
func<<<1,1>>>(d_a, d_stridx, num_str);
cudaDeviceSynchronize();
}
$ nvcc -arch=sm_20 -o t389 t389.cu
$ cuda-memcheck ./t389
========= CUDA-MEMCHECK
string[0]: some text
string[1]: rand txt
string[2]: text
========= ERROR SUMMARY: 0 errors
$