C++ 推力CUDA将char*分配给对象的设备_向量

C++ 推力CUDA将char*分配给对象的设备_向量,c++,cuda,thrust,C++,Cuda,Thrust,我无法将主机_向量深度复制到设备_向量。我认为我在修改设备向量中存储的元素的值时遇到了问题。您可以在底部找到一个可编译版本,但问题代码如下(我在触发分段错误的行上加了星号): 推力::主机\向量主机排序(大小); 推力:主机向量hostToSortRow(大小); 对于(int i=0;ivalue=deviceString; } 当我们到达实际任务时会发生什么 DeviceCharar->value=deviceString 它抛出一个分段错误。我是CUDA的新手,如果有明显的答案,我很抱歉

我无法将主机_向量深度复制到设备_向量。我认为我在修改设备向量中存储的元素的值时遇到了问题。您可以在底部找到一个可编译版本,但问题代码如下(我在触发分段错误的行上加了星号):

推力::主机\向量主机排序(大小);
推力:主机向量hostToSortRow(大小);
对于(int i=0;ilength=尺寸限制;
****DeviceCharar->value=deviceString;
}
当我们到达实际任务时会发生什么
DeviceCharar->value=deviceString 它抛出一个分段错误。我是CUDA的新手,如果有明显的答案,我很抱歉,但是我还没有找到很多人在设备上分配char*的例子

完整的可编译版本在这里

#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/reduce.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>

#include <thrust/reduce.h>


typedef struct{

    char * value;
    int length;
} CharArr;


struct CharArrayCmp{
    __host__ __device__
      bool operator()(const CharArr & o1, const CharArr & o2) {
          return this->compare(o1.value,o1.length,o2.value,o2.length);
      }

    __host__ __device__ bool compare (const char * src, int lenSrc, const char * dst, int lenDest)
    {
        int end;
        if(lenSrc > lenDest){
            end = lenDest;
        }else{
            end = lenSrc;
        }
        for(int i = 0; i < end; i++){
            if(src[i] > dst[i]){
                return false;
            }else if(src[i] < dst[i]){
                return true;
            }
        }
        if(lenSrc >= lenDest){
            return false;
        }
        return true;
    }
};


void sortCharArrayHost(char ** arrayToSort, long long * arrayToSortRow,long long size){
    std::cout <<"about to start LongIndex" <<std::endl;

            thrust::host_vector<CharArr> hostToSort(size);
            thrust::host_vector<long long> hostToSortRow(size);
            for(int i =0; i < size; i++){
                CharArr sortRow;
                sortRow.value = arrayToSort[i];
                sortRow.length = strlen(arrayToSort[i]);
                hostToSort[i] = sortRow;
                hostToSortRow[i] = arrayToSortRow[i];
            }
            /*thrust::device_vector<CharArr> deviceArrayToSort =hostToSort;
            //thrust::copy(hostToSort.begin(),hostToSort.end(),deviceArrayToSort.begin());
//           = ;// (arrayToSort,arrayToSort + size);
            thrust::device_vector<long long> deviceArrayToSortRow = hostToSortRow;//(arrayToSortRow,arrayToSortRow + size);

           // thrust::sort(deviceArrayToSort.begin(),deviceArrayToSort.end());
            for(int i = 0; i < size; i++){
                char * deviceString = 0;
                char * hostString = hostToSort[i].value;
                int size = strlen(hostString)*sizeof(char);
                int cudaStatus;
                CharArr * deviceCharArr = (&deviceArrayToSort[i]).get();
                cudaStatus = cudaMalloc((void **) deviceString,size);
                cudaStatus = cudaMemcpy(deviceString,hostString,size,cudaMemcpyHostToDevice);

                (&deviceArrayToSort[i]).get()->value = "";
            }
*/
//          thrust::sort_by_key(deviceArrayToSort.begin(),deviceArrayToSort.end(),deviceArrayToSortRow.begin(),CharArrayCmp());
            thrust::sort_by_key(hostToSort.begin(),hostToSort.end(),hostToSortRow.begin(),CharArrayCmp());

            //copy the contents back into our original array to sort now sorted
          //  hostToSort = deviceArrayToSort;
            for(int i =0; i < size; i++){
                arrayToSort[i] = hostToSort[i].value;
            }
//          thrust::copy(deviceArrayToSortRow.begin(),deviceArrayToSortRow.end(),arrayToSortRow);
            thrust::copy(hostToSortRow.begin(),hostToSortRow.end(),arrayToSortRow);


}
void sortCharArrayDevice(char ** arrayToSort, long long * arrayToSortRow,long long size){
    std::cout <<"about to start LongIndex" <<std::endl;

            thrust::host_vector<CharArr> hostToSort(size);
            thrust::host_vector<long long> hostToSortRow(size);
            for(int i =0; i < size; i++){
                CharArr sortRow;
                sortRow.value = arrayToSort[i];
                sortRow.length = strlen(arrayToSort[i]);
                hostToSort[i] = sortRow;
                hostToSortRow[i] = arrayToSortRow[i];
            }
            thrust::device_vector<CharArr> deviceArrayToSort =hostToSort;
            //thrust::copy(hostToSort.begin(),hostToSort.end(),deviceArrayToSort.begin());
//           = ;// (arrayToSort,arrayToSort + size);
            thrust::device_vector<long long> deviceArrayToSortRow = hostToSortRow;//(arrayToSortRow,arrayToSortRow + size);

           // thrust::sort(deviceArrayToSort.begin(),deviceArrayToSort.end());
            for(int i = 0; i < size; i++){

                char * hostString = hostToSort[i].value;
                int sizeString = strlen(hostString);
                char * deviceString = 0;

                CharArr * deviceCharArr = (&deviceArrayToSort[i]).get();
                cudaMalloc((void **) deviceString,sizeString);
                cudaMemcpy(deviceString,hostString,sizeString,cudaMemcpyHostToDevice);
                deviceCharArr->length = sizeString;
                deviceCharArr->value = deviceString;
            }

            thrust::sort_by_key(deviceArrayToSort.begin(),deviceArrayToSort.end(),deviceArrayToSortRow.begin(),CharArrayCmp());
        //copy the contents back into our original array to sort now sorted
            for(int i =0; i < size; i++){
                arrayToSort[i] = (&deviceArrayToSort[i]).get()->value;
            }
            thrust::copy(deviceArrayToSortRow.begin(),deviceArrayToSortRow.end(),arrayToSortRow);



}
int main()
{
    char ** charArr = new char*[10];

    charArr[0] = "zyxw";
    charArr[1] = "abcd";
    charArr[2] = "defg";
    charArr[3] = "werd";
    charArr[4] = "aasd";
    charArr[5] = "zwedew";
    charArr[6] = "asde";
    charArr[7] = "rurt";
    charArr[8] = "ntddwe";
    charArr[9] = "erbfde";

    long long * rows = new long long[10];
    for(int i = 0; i < 10;i++ ){
        rows[i] = i;
    }

    sortCharArrayHost(charArr,rows,10);

    for(int i = 0; i < 10; i++){
        std::cout<<"Row is "<<rows[i]<<" String is "<<charArr[i]<<std::endl;

    }


    charArr[0] = "zyxw";
    charArr[1] = "abcd";
    charArr[2] = "defg";
    charArr[3] = "werd";
    charArr[4] = "aasd";
    charArr[5] = "zwedew";
    charArr[6] = "asde";
    charArr[7] = "rurt";
    charArr[8] = "ntddwe";
    charArr[9] = "erbfde";


    for(int i = 0; i < 10;i++ ){
        rows[i] = i;
    }
    sortCharArrayDevice(charArr,rows,10);

        for(int i = 0; i < 10; i++){
            std::cout<<"Row is "<<rows[i]<<" String is "<<charArr[i]<<std::endl;

        }

}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类型定义结构{
字符*值;
整数长度;
}查拉尔;
结构CharArrayCmp{
__主机设备__
布尔运算符(){
返回此->比较(o1.value,o1.length,o2.value,o2.length);
}
__主机设备比较(常量字符*src,int lenSrc,常量字符*dst,int lenDest)
{
内端;
如果(lenSrc>lenDest){
结束=最辉煌;
}否则{
end=lenSrc;
}
for(int i=0;idst[i]){
返回false;
}else if(src[i]=lenDest){
返回false;
}
返回true;
}
};
void sortCharArrayHost(字符**数组排序,长-长*数组排序,长-长大小){

正如Jackolanten已经指出的,这是不可接受的:

// this creates an allocation on the device
thrust::device_vector<CharArr> deviceArrayToSort =hostToSort;
// this takes the (device) address an element and assigns it to a pointer variable
CharArr * deviceCharArr = (&deviceArrayToSort[i]).get();
// this then dereferences a device pointer in host code which is illegal
deviceCharArr->length = sizeString;

正如JackOLantern已经指出的,这是不可接受的:

// this creates an allocation on the device
thrust::device_vector<CharArr> deviceArrayToSort =hostToSort;
// this takes the (device) address an element and assigns it to a pointer variable
CharArr * deviceCharArr = (&deviceArrayToSort[i]).get();
// this then dereferences a device pointer in host code which is illegal
deviceCharArr->length = sizeString;

通过
CharArr*deviceCharArr=(&DeviceArrayTorSort[i]).get();
您正在将主机端指针(
deviceCharArra
)分配给设备内存位置(
(&DeviceArrayTorSort[i]).get()
)。然后在主机上执行操作
devicecharar->length=sizeString;
,涉及对主机无意义的内存位置。通过
CharArr*devicecharar=(&deviceArrayToSort[i]).get();
您正在将主机端指针(
devicecharra
)分配给设备内存位置(
(&deviceArrayToSort[i]).get()
)。然后在主机上执行操作
devicecharar->length=sizeString;
,涉及一个对主机没有意义的内存位置。Robert你是我在论坛上遇到的最有帮助的人。非常感谢,这正是我需要帮助理解的。这一切现在对我来说都很有意义。谢谢你的建议ce关于推力和什么在排序中更有效。我将花更多的时间阅读cuda文档。很明显,我知道的还不够。Robert你是我在论坛上遇到的最有帮助的人。非常感谢这正是我需要帮助理解的。这一切现在对我来说都很有意义。谢谢你关于推力和排序的建议什么在分类方面更有效。我将花更多的时间阅读cuda文档。很明显,我知道的还不够多。
$ cat t439.cu
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>
#include <thrust/copy.h>

#define NUM_STRINGS 10



struct stringCmp{

  const char * strings;

  stringCmp(char * _strings) : strings(_strings) {}

template<typename myTuple>
    __host__ __device__
      bool operator()(const myTuple & o1, const myTuple & o2) {
        int idxSrc = thrust::get<0>(o1);
        int lenSrc = thrust::get<1>(o1);
        int idxDst = thrust::get<0>(o2);
        int lenDst = thrust::get<1>(o2);
        int end;
        if(lenSrc > lenDst){
            end = lenDst;
        }else{
            end = lenSrc;
        }
        for(int i = 0; i < end; i++){
            if(strings[idxSrc+i] > strings[idxDst+i]){
                return false;
            }else if(strings[idxSrc+i] < strings[idxDst+i]){
                return true;
            }
        }
        if(lenSrc >= lenDst){
            return false;
        }
        return true;
    }
};

void sortCharArrayDevice(char ** arr, int *rows, int num_str){

    thrust::host_vector<char> h_strings;
    thrust::host_vector<int>  h_st_idx(num_str);
    thrust::host_vector<int>  h_len(num_str);
    thrust::host_vector<int>  h_rows(num_str);
    // concatenate strings
    // assume no zero length strings
    h_st_idx[0] = 0;
    for (int i = 0; i < num_str; i++){
      int sidx = 0;
      while (arr[i][sidx] != '\0'){
        h_strings.push_back(arr[i][sidx]);
        sidx++;}
      h_len[i] = sidx;
      if (i < num_str-1) h_st_idx[i+1] = h_st_idx[i] + sidx;
      h_rows[i] = rows[i];
      }
    // copy data to device
    thrust::device_vector<char> d_strings = h_strings;
    thrust::device_vector<int>  d_st_idx = h_st_idx;
    thrust::device_vector<int>  d_len = h_len;
    thrust::device_vector<int>  d_rows = h_rows;
    // sort on device
    thrust::sort(thrust::make_zip_iterator(thrust::make_tuple(d_st_idx.begin(), d_len.begin(), d_rows.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_st_idx.end(), d_len.end(), d_rows.end())), stringCmp(thrust::raw_pointer_cast(d_strings.data())));
    thrust::copy(d_rows.begin(), d_rows.end(), rows);
}


int main()
{
    char ** charArr = new char*[NUM_STRINGS];

    charArr[0] = "zyxw";
    charArr[1] = "abcd";
    charArr[2] = "defg";
    charArr[3] = "werd";
    charArr[4] = "aasd";
    charArr[5] = "zwedew";
    charArr[6] = "asde";
    charArr[7] = "rurt";
    charArr[8] = "ntddwe";
    charArr[9] = "erbfde";

    int * rows = new int[NUM_STRINGS];
    for(int i = 0; i < NUM_STRINGS;i++ ){
        rows[i] = i;
    }

    sortCharArrayDevice(charArr,rows,NUM_STRINGS);

        for(int i = 0; i < NUM_STRINGS; i++){
            std::cout<<"Row is "<<rows[i]<<" String is "<<charArr[rows[i]]<<std::endl;

        }

}
$ nvcc -arch=sm_20 -o t439 t439.cu
$ ./t439
Row is 4 String is aasd
Row is 1 String is abcd
Row is 6 String is asde
Row is 2 String is defg
Row is 9 String is erbfde
Row is 8 String is ntddwe
Row is 7 String is rurt
Row is 3 String is werd
Row is 5 String is zwedew
Row is 0 String is zyxw
$