Cuda::thrust:与Device_vector进行压缩操作

Cuda::thrust: Performing compact operation with Device_vector

我对 Cuda 还是很陌生,虽然 Whosebug 用户给了我一个描述性示例,说明如何使用 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*/

我收到错误信息:

class "thrust::device_vector>" has no member "iterator_category"

和:

no instance of overloaded function "thrust::copy_if" matches the argument list

我已经坚持了一段时间,如果有任何关于如何更正这些错误或更准确地转换上述示例的建议,我们将不胜感激。我之前关于此事的问题

您可能想阅读 thrust quick start guide

这会给你带来麻烦:

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函数的return value是一个迭代器。您不能将其分配给向量。矢量与迭代器不同。 Host_results 是一个向量。

不确定这是什么:

host_results=device_results;

您是否真的在某处有一个也以小写开头的变量或向量 h?因为 host_resultsHost_results

不一样

这是一个完整的示例,演示了如何对任意长度的设备向量执行 thrust::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,
$