私はAoSからSoAへのアプローチをメモリの融合を利用してリファクタリングしています。その目的のために、私は共通のキーで縮小され、出力ベクトルの値を計算するために使われる2つのベクトルを持っています。元のコードは、私がエミュレートしたい単一のファンクタでこれを行いました。本質的reduce_by_key()から2つの縮小ベクトルの関数として出力
:RᵢとSᵢが同じ鍵によって低減ベクトルであり、Oᵢは、対応する出力ベクトルである
Oᵢ=Rᵢ/Sᵢ、。
以下は私が何をしようとしている例示コードです:
typedef tuple<int,int> Tuple;
struct BinaryTupleOp : public thrust::binary_function<Tuple const &, Tuple const &, int>
{
__host__ __device__
int operator()(Tuple const & lhs, Tuple const & rhs) const {
// get<0> = vals, get<1> = other_vals
return (get<0>(lhs) + get<0>(rhs))/(get<1>(lhs) + get<1>(rhs));
}
};
int main(int argc, char ** argv)
{
const int N = 7;
device_vector<int> keys(N);
keys[0] = 1; // represents sorted keys
keys[1] = 1;
keys[2] = 2;
keys[3] = 2;
keys[4] = 3;
keys[5] = 3;
keys[6] = 3;
device_vector<int> vals(N);
vals[0] = 6; // just some random numbers
vals[1] = 3;
vals[2] = 9;
vals[3] = 4;
vals[4] = 6;
vals[5] = 1;
vals[6] = 5;
device_vector<int> other_vals(N);
other_vals[0] = 4; // more randomness
other_vals[1] = 1;
other_vals[2] = 3;
other_vals[3] = 6;
other_vals[4] = 2;
other_vals[5] = 5;
other_vals[6] = 7;
device_vector<int> new_keys(N);
device_vector<int> output(N);
typedef device_vector<int>::iterator Iterator;
thrust::pair<Iterator, Iterator> new_end;
thrust::equal_to<int> binary_pred;
new_end = thrust::reduce_by_key(keys.begin(), keys.end(),
make_zip_iterator(make_tuple(vals.begin(), other_vals.begin())),
new_keys.begin(),
output.begin(),
binary_pred,
BinaryTupleOp());
Iterator i = new_keys.begin();
Iterator j = output.begin();
for (;
i != new_end.first;
i++, j++) {
std::cout << "key " << *i << " sum " << *j << endl;
}
return 0;
}
残念ながら、これはerror: no operator "=" matches these operands
、error: no suitable conversion function from "InputValueType" to "TemporaryType" exists
、およびerror: no suitable conversion function from "const thrust::tuple<int, int, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type>" to "int" exists
などのエラーを生成します。私はそれが問題の究極のソースだと思うので、ファンクタのパラメータ型の変種で遊んだことがありますが、無駄です。
回避策として、私はおそらく別々に2つの縮小を分解し、変換を使用して出力ベクトルを作成します。 (おそらく、さまざまなtransform_reduce()
コールを一緒にリンクすることを示唆しているかもしれませんが、私は、AFAIKが存在しないreduce_transform()
のような逆を欲しそうです)。
タイムリーで、長く、適切な対応をいただき、ありがとうございました。あなたのポーズされたソリューションは、確かに私が探していたものでした。 私はreduce_by_key' 'のためにRTFDだったとき、私はあなたが親切に強調されていること、この詳細を逃した: は' InputIterator2のVALUE_TYPEは、自然にそれが直接、単一のPODにタプルを割り当てるには少し難しいですが、OutputIterator2のvalue_type.' に変換され、それは私が不注意でやろうとしていたものです。 私は今すぐ元のコードに適切な変更を適用しています。再びありがとう。 –