Thrust::inner_productは、単一の関数呼び出しでそれを行います。元のアイデアも機能させることができます (2 つのベクトルを一緒に圧縮して を使用thrust::transform_reduce
)。このコードは両方の方法を示しています。
#include <iostream>
#include <thrust/tuple.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/transform.h>
#include <thrust/device_vector.h>
#include <thrust/inner_product.h>
#include <thrust/functional.h>
#define N 2
struct zdiffsq{
template <typename Tuple>
__host__ __device__ float operator()(Tuple a)
{
float result = thrust::get<0>(a) - thrust::get<1>(a);
return result*result;
}
};
struct diffsq{
__host__ __device__ float operator()(float a, float b)
{
return (b-a)*(b-a);
}
};
int main(){
thrust::device_vector<float> oldvector(N);
thrust::device_vector<float> newvector(N);
oldvector[0] = 1.0f; oldvector[1] = 2.0f;
newvector[0] = 2.0f; newvector[1] = 5.0f;
float result = thrust::inner_product(oldvector.begin(), oldvector.end(), newvector.begin(), 0.0f, thrust::plus<float>(), diffsq());
std::cout << "Result: " << result << std::endl;
float result2 = thrust::transform_reduce(thrust::make_zip_iterator(thrust::make_tuple(oldvector.begin(), newvector.begin())), thrust::make_zip_iterator(thrust::make_tuple(oldvector.end(), newvector.end())), zdiffsq(), 0.0f, thrust::plus<float>());
std::cout << "Result2: " << result2 << std::endl;
}
スラストプレースホルダーを使用して、内積の例で使用されているファンクター定義を削除することも調査できます。
独自の CUDA コードを作成する場合でも、並列リダクションや並べ替えなどの頻繁に使用されるアルゴリズムに対する現在の標準的な推奨事項は、cubを使用することです。
はい、CUDA 並列リダクションのサンプルとそれに付随するプレゼンテーションは、高速な並列リダクションの優れた基本的な紹介です。