私はCUDAを初めて使い、ファンクタに少し問題があります。私はthrust :: vectorのベクトルをファンクタに入力しようとしています。現在私はベクトルを入力して各要素に何かを行い、thrust :: for_eachを使って修正したベクトルを返すことができますが、もし私がファンクタでベクトルをソートしたいのであれば、ベクトル全体を一度に入力できるようにする必要がありますファンクタは全体としてそれに作用することができます。これを行う方法はありますか?functorがthrust :: vector全体を見て、並べ替えができるようにするにはどうすればいいですか?
以下のコードはコンパイルされますが、ソートされたベクトルは返されません。しかし
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <thrust/functional.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/reduce.h>
#include <thrust/transform_reduce.h>
#include <thrust/transform.h>
#include <thrust/sort.h>
#include <thrust/execution_policy.h>
#include <thrust/system/cuda/execution_policy.h>
#include <thrust/tuple.h>
#include <thrust/count.h>
#include <thrust/sequence.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/for_each.h>
#include <ctime>
#include <cstdio>
#include <cassert>
using namespace std;
template<typename T>
struct sort_vector
{
__host__ __device__ thrust::device_vector<float> operator() (thrust::tuple<thrust::device_vector<float>, thrust::device_vector<float>> x)
{
thrust::device_vector<float> y = thrust::get<0>(x);
thrust::sort(y.begin(), y.end());
return thrust::get<1>(x) = y;
}
};
int main() {
thrust::device_vector<float> d_fraction(5);
d_fraction[0] = 1;
d_fraction[1] = 5;
d_fraction[2] = 3;
d_fraction[3] = 2;
d_fraction[4] = 4;
cout << "original" << endl;
int f = 0;
while (f < 5){
cout << d_fraction[f] << endl;
f++;
}
cudaStream_t s1;
cudaStreamCreate(&s1);
thrust::device_vector<float> result1(5);
thrust::for_each(thrust::cuda::par.on(s1),
thrust::make_zip_iterator(thrust::make_tuple(d_fraction.begin(), result1.begin())),
thrust::make_zip_iterator(thrust::make_tuple(d_fraction.end(), result1.end())), sort_vector<thrust::device_vector<float>>());
cudaStreamSynchronize(s1);
cout << "sorted" << endl;
int d = 0;
while (d < 5){
cout << Sresult2[d] << endl;
d++;
}
cudaStreamDestroy(s1);
return 0;
}
、私は
_host__ __device__ thrust::device_vector<float> operator() (thrust::tuple<thrust::device_vector<float> &, thrust::device_vector<float> &> x)
コードは、もはやコンパイルなどの参照を使用しないようにしてください。
ファンクタがベクトル全体を見ることができるように、ベクトルの参照ポインタをキャストする必要がありますか? または、問題が、値によってベクトルを渡している可能性があります。また、ベクトルをファンクタに渡すことを知らない別の方法がありますか?
@Robert_Crovellaこれはうまくいきました、ありがとうございます!クイックフォローアップの質問。ファンクタに複数のポインタを送ることは可能ですか?このようにして2つの推力ベクトルを加算することができますか?私は既存のコードを修正しようとしていますが、メンバー関数の無効な再宣言などのエラーを送信しています。 – gracie
はい、複数の初期化パラメータをファンクタに送ることができます。これは実際には純粋なC++アクティビティです(ファンクタは実際には推論に固有のものではなく、C++の動物です)。複数の値を受け取り、それらをクラスデータメンバに割り当てるファンクタのコンストラクタを作成するだけで済みます。例としては、[copy_func]コンストラクタが必要とする[here](http://stackoverflow.com/questions/35736801/making-the-number-of-key-occurances-equal-using-cuda-thrust/35737950#35737950)があります。 2つのパラメータ。 2つのポインタを渡すことはできませんが、多くのパラメータを渡すことはできません。 –
実際、私の答えにリンクしている回答には、複数のパラメータを持つファンクタ( 'sort_functor')が含まれています。そこでの初期化は、デフォルト以外のコンストラクタを使用するのではなく、ファンクタオブジェクトをインスタンス化し、動的パラメータの初期化を使用して別々に実行されます。いずれの方法も実行可能です。 –