简体   繁体   中英

Cuda::thrust: Performing compact operation with Device_vector

I'm still fairly new to Cuda and while a stackoverflow user gave me a descriptive example on how to use thrust::copy_if to compact an array of known size on the host (as I worded my question badly), I've been unable to convert the approach to use device_vectors (to deal with inputted arrays of unknown size on the device).

I'm attempting to generate a compacted list of the positions of all the elements in a vector which match a user specified predicate. The working example I was given is:

#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;
}

I've tried to modify the code to use device vectors (and compute on the device) as follows:

#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*/

I get errors stating that:

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

and:

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

I've been stuck on this for a while and any suggestions on how to correct those errors, or more accurately convert the above sample, would be greatly appreciated. My previous question on this matter can be found here:

You might want to read the thrust quick start guide .

This will get you in trouble:

thrust::host_vector<int> Host_results;

that creates a vector of zero size. Later when you do this:

thrust::device_vector<int> Device_results = Host_results;

You've created another vector of zero size. Although these will not create compile errors, if you try to use these (eg by copying something into them) without a proper size allocation, you're going to have trouble at run-time.

This is also wrong:

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

The return value of the thrust::copy_if function is an iterator . You cannot assign it to a vector. A vector is not the same as an iterator. Host_results is a vector.

Not sure what this is:

host_results=device_results;

Do you actually have a variable or vector somewhere that also begins with a lower case h ? Because host_results is not the same as Host_results

Here's a complete worked example demonstrating how to do thrust::copy_if on device vectors of arbitrary length:

$ 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,
$

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM