如何使用 CUDA 将 std::vector<std::string> 复制到 GPU 设备
How to copy std::vector<std::string> to GPU device with CUDA
我正在从文件中读取行,并希望通过 GPU 对每一行执行一些计算。
我面临的问题是,到目前为止,我曾经以恒定大小复制一个 int 数组,现在我有一个字符串向量,每个字符串的大小都不同。我正在使用:
std::vector<std::string> lines;
我使用了一个常量大小来复制数组。 像这样:
err = cudaMemcpy(_devArr, tmp, count * sizeof(unsigned int) * 8, cudaMemcpyHostToDevice);
但我不确定我是否完全理解它如何与向量一起工作。如何寻址和复制字符串向量?我可以以某种方式复制它并仍然像带有线程+块索引的数组一样访问它吗?
*使用最新的 CUDA 10.2 和 CUDA RTX 2060 显卡
您需要将字符串平展为包含所有字符串的连续内存块。我的建议是使用两个(总(块来执行此操作,一个包含组合的字符串数据,另一个包含每个字符串的索引。
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++17复制构造函数,在std::unordereded_map上进行深度复制
- std::ofstream 作为类成员删除复制构造函数?
- 使用 memcpy() 复制到 std::chrono::milliseconds 会给出错误 -Werror=clas
- 在什么条件下使用 std::memcpy 在对象之间复制是安全的?
- 创建一个没有复制构造函数的类的 std::vector 的 std::vector
- 在 lambda 中锁定 std::shared_ptr 的复制操作
- std::p ackaged_task 应该删除带有 const 参数的复制 c'tor
- std::元组分配和复制/移动异常保证
- 转发复制的 std::tuple
- 使用std ::复制复制阵列时获取细分故障
- 将std ::复制转换为std :: memcpy不起作用
- STD ::复制在调试构建中失败
- 将指针而不是迭代器传递到std ::复制
- memcpy或std ::复制我的特定应用程序
- 我可以使用STD ::复制将数据的位模式从整数向量复制到一系列未签名的字符
- C++:std::复制失败,出现访问冲突读取位置错误
- 为什么memcpy无法复制特征矩阵数据,但std::复制成功
- std::复制钩子
- c++ std::复制结果不同于字符串构造函数
- C++11 std::复制内部函数