Cuda::推力:使用Device_vector执行紧凑操作

Cuda::thrust: Performing compact operation with Device_vector

本文关键字:执行 操作 vector 推力 使用 Device Cuda      更新时间:2023-10-16

我对Cuda还很陌生,虽然一位stackerflow用户给了我一个关于如何使用thrust::copy_if在主机上压缩已知大小的数组的描述性示例(因为我的问题措辞不好),但我一直无法将该方法转换为使用device_vectors(处理设备上输入的未知大小的数组)。

我试图生成一个向量中所有元素位置的压缩列表,这些元素与用户指定的谓词相匹配。我得到的工作示例是:

#include <thrust/copy.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/functional.h>
#include <iostream>
using namespace thrust::placeholders;
int main()
{
    const int N = 10;
    int objectArray[N] = { 1, 11, 7, 2, 7, 23, 6, 6, 9, 11 };
    int results[N]={0};
    int* end = thrust::copy_if(thrust::make_counting_iterator(0), thrust::make_counting_iterator(N), objectArray, results, _1 == 7);
    thrust::copy(results, results+N, std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl << "result count = " << end-results << std::endl;
    return 0;
}

我尝试修改代码以使用设备矢量(并在设备上进行计算),如下所示:

#include <thrust/copy.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/functional.h>
#include <iostream>
using namespace thrust::placeholders;
int soughtElement=7;
reader.open("Numeric_1a40Coords.txt");
reader >> sizeOfProteinChain; //This returns the size of the input
reader.close();
thrust::host_vector<int> Host_names(sizeOfProteinChain);
thrust::host_vector<int> Host_results;
ImportNumericNameValues("Numeric_1a40Coords.txt", Host_names); //This populates the vector with "sizeOfProteinChain" number of elements
thrust::device_vector<int> Device_names = Host_Names;
thrust::device_vector<int> Device_results = Host_results;
Host_results = thrust::copy_if(thrust::make_counting_iterator(0), thrust::make_counting_iterator(sizeOfProteinChain), Device_names, Device_results, _1 == soughtElement);
host_results=device_results;
for (int i=0;i<sizeOfProteinChain;i++)
cout<< host_results[i]<<" ";
cout<<endl;
/*Not sure how to get the resulting number of compacted position elements with device vectors instead of pointer arrays*/

我收到错误声明:

类"thrust::device_vector>"没有成员"迭代器类别"

和:

没有重载函数"thrust::copy_if"的实例与参数列表

我已经在这个问题上坚持了一段时间,如果有任何关于如何纠正这些错误,或者更准确地转换上面的样本的建议,我将不胜感激。我之前关于这个问题的问题可以在这里找到:

您可能需要阅读推力快速启动指南。

这会给你带来麻烦:

thrust::host_vector<int> Host_results;

它创建了一个零大小的向量。稍后当你这样做时:

thrust::device_vector<int> Device_results = Host_results;

您创建了另一个零大小的矢量。虽然这些不会产生编译错误,但如果您试图在没有适当大小分配的情况下使用这些错误(例如,通过将某些内容复制到其中),则在运行时会遇到问题。

这也是错误的:

Host_results = thrust::copy_if(thrust::make_counting_iterator(0), thrust::make_counting_iterator(sizeOfProteinChain), Device_names, Device_results, _1 == soughtElement);

thrust::copy_if函数的返回值是迭代器。不能将其指定给向量。向量与迭代器不同。CCD_ 2是一个矢量。

不确定这是什么:

host_results=device_results;

你真的有一个以小写h开头的变量或向量吗?因为host_resultsHost_results 不同

以下是一个完整的示例,演示了如何在任意长度的设备向量上执行推力::copy_if:

$ cat t808.cu
#include <thrust/copy.h>
#include <thrust/device_vector.h>
#include <thrust/iterator/counting_iterator.h>
#include <iostream>
#define COPY_VAL 7
using namespace thrust::placeholders;
int main(){
  int objectArray[] = { 1, 11, 7, 2, 7, 23, 6, 6, 9, 11 };
  int dsize = sizeof(objectArray)/sizeof(int);
  int results[dsize];
  thrust::device_vector<int> d_obj(objectArray, objectArray+dsize);
  thrust::device_vector<int> d_res(dsize);
  int resultCount = thrust::copy_if(thrust::make_counting_iterator(0), thrust::make_counting_iterator(dsize), d_obj.begin(),  d_res.begin(), (_1 == COPY_VAL)) - d_res.begin();
  thrust::copy(d_res.begin(), d_res.end(), results);
  std::cout << "resultCount = " << resultCount << std::endl << "results: " << std::endl;
  thrust::copy(d_res.begin(), d_res.end(), std::ostream_iterator<int>(std::cout, ", "));
  std::cout << std::endl;
  return 0;
}

$ nvcc -o t808 t808.cu
$ ./t808
resultCount = 2
results:
2, 4, 0, 0, 0, 0, 0, 0, 0, 0,
$