c++ - 如何使用 CUDA 将 std::vector<std::string> 复制到 GPU 设备

标签 c++ string cuda gpu stdvector

我正在从文件中读取行,并希望由 GPU 对每一行执行一些计算。

我面临的问题是,到目前为止,我曾经以恒定大小复制一个 int 数组,现在我有一个字符串 vector ,并且每个字符串的大小都不同。我正在使用:

std::vector<std::string> lines;

我使用常量大小来复制数组。像这样:

err = cudaMemcpy(_devArr, tmp, count * sizeof(unsigned int) * 8, cudaMemcpyHostToDevice);

但我不确定我是否完全理解它如何与 vector 一起使用。如何寻址和复制字符串 vector ?我可以以某种方式复制它并仍然像具有线程+ block 索引的数组一样访问它吗?

*使用最新的CUDA 10.2和CUDA RTX 2060显卡

最佳答案

您需要将字符串压平到包含所有字符串的连续内存块中。我的建议是使用两个(总共) block 来完成此操作,一个包含组合字符串数据,另一个包含每个字符串的索引。

std::string combined; //Works perfectly fine so long as it is contiguously allocated
std::vector<size_t> indexes; //You *might* be able to use int instead of size_t to save space
for(std::string const& line : lines) {
    combined += line;
    indexes.emplace_back(combined.size());
}
/* If 'lines' initially consisted of ["Dog", "Cat", "Tree", "Yard"], 'combined' is now
 * "DogCatTreeYard", and 'indexes' is now [3, 6, 10, 14].
 */

//I'm hoping I am writing these statements correctly; I don't specifically have CUDA experience
err = cudaMemcpy(_devArr, combined.data(), combined.size(), cudaMemcpyHostToDevice);
err = cudaMemcpy(_devArr2, indexes.data(), indexes.size() * sizeof(size_t), cudaMemcpyHostToDevice);

然后,在设备本身中,您将能够根据需要读取每个字符串。我不熟悉 CUDA 使用的语法,因此我将用 OpenCL 语法来编写此内容,但原则应该干净、直接地转换为 CUDA;如果我错了,有人纠正我。

kernel void main_func(
    global char * lines, //combined string data
    global ulong * indexes, //indexes telling us the beginning and end of each string
    ulong indexes_size, //number of strings being analyzed
    global int * results //space to return results back to Host
) {
    size_t id = get_global_id(0);//"Which String are we examining?"
    if(id >= indexes_size) //Bounds Checking
        return;
    global char * string; //Beginning of the string
    if(id == 0) //First String
        string = lines;
    else
        string = (lines + indexes[id-1]);
    global char * string_end = (lines + indexes[id]); //end of the string
    for(; string != string_end; string++) {
        if(*string == 'A') {
            results[id] = 1; //We matched the criteria; we'll put a '1' for this string
            return;
        }
    }
    results[id] = 0; //We did not match. We'll put a '0' for this string
}

在初始字符串列表上执行此代码的结果是,对于任何包含 A 的字符串,它将得到结果 1;如果没有,则得到结果 0。这里的逻辑应该可以干净地转移到 CUDA 使用的特定语法;如果不是请告诉我。

关于c++ - 如何使用 CUDA 将 std::vector<std::string> 复制到 GPU 设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59255418/

相关文章:

c++ - 在解析器中提升 Spirit 段错误

c++ - 如何在 C++ 中将 std::string 显示到 CEdit 中

c++ - 启动多个线程,只等待一个线程结束获取结果

string - 使用 VBA 将可变文本字符串(时间戳)插入单元格

c - 使用 cudaBindTexture2D 将二维数组绑定(bind)到 GPU 的纹理内存会产生错误

c++ - 我应该为这个艺术项目使用哪个 IDE?

c++ - 从队列创建双向链表查找中位数与使用数组的效率

python - del语句的功能

c - 从最后一次出现的字符开始缩短 C 字符串?

gcc - 链接到 libcuda.so 时出现问题