配列内の非ゼロ要素のインデックスを取得するために、反復子のカウントと組み合わせた Thrust ライブラリの Thrust::copy_if 関数を使用しています。コピーされた要素の数も取得する必要があります。
「counting_iterator.cu」の例のコードを使用していますが、私のアプリケーションでは事前に割り当てられた配列を再利用する必要があるため、それらを throw::device_ptr でラップしてから、thrust::copy_if 関数に渡します。これはコードです:
using namespace thrust;
int output[5];
thrust::device_ptr<int> tp_output = device_pointer_cast(output);
float stencil[5];
stencil[0] = 0;
stencil[1] = 0;
stencil[2] = 1;
stencil[3] = 0;
stencil[4] = 1;
device_ptr<float> tp_stencil = device_pointer_cast(stencil);
device_vector<int>::iterator output_end = copy_if(make_counting_iterator<int>(0),
make_counting_iterator<int>(5),
tp_stencil,
tp_output,
_1 == 1);
int number_of_ones = output_end - tp_output;
コードの最後の行にコメントを付けると、関数は出力配列を正しく埋めます。ただし、コメントを外すと、次のコンパイル エラーが発生します。
1>C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include\thrust/iterator/iterator_adaptor.h(223): エラー: 演算子 "-" がこれらのオペランドに一致しません
1> オペランドの型は次のとおりです: int *const - const 推力::device_ptr
1> 中に検出: 1> "thrust::iterator_adaptor::difference_type throw::iterator_adaptor::distance_to(const Thrust::iterator_adaptor &) const [with Derived=thrust::detail::normal_iterator>, Base=thrust: のインスタンス化: :device_ptr, Value=thrust::use_default, System=thrust::use_default, Traversal=thrust::use_default, Reference=thrust::use_default, Difference=thrust::use_default, OtherDerived=thrust::device_ptr, OtherIterator=int *, V=signed int、S=thrust::device_system_tag、T=thrust::random_access_traversal_tag、R=thrust::device_reference、D=ptrdiff_t]" 1> C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\ include\thrust/iterator/iterator_facade.h(181): ここで 1> "Facade1::difference_type 推力::iterator_core_access::distance_from(const Facade1 &,const Facade2 &, Thrust::detail::true_type) [with Facade1=thrust::detail::normal_iterator>, Facade2=thrust::device_ptr]" 1> C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5. 5\include\thrust/iterator/iterator_facade.h(202): ここで 1> "thrust::detail::distance_from_result::type throw::iterator_core_access::distance_from(const Facade1 &, const Facade2 &) のインスタンス化 [with Facade1 =thrust::detail::normal_iterator>, Facade2=thrust::device_ptr]" 1> C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include\thrust/iterator/iterator_facade.h(506):ここで 1> 「thrust::detail::distance_from_result、thrust::iterator_facade>::type 推力::operator-(const 推力::iterator_facade &、const 推力::iterator_facade &) のインスタンス化 [with Derived1=thrust::detail] ::normal_iterator>, Value1=signed int, System1=thrust::device_system_tag, Traversal1=thrust::random_access_traversal_tag, Reference1=thrust::device_reference, Difference1=signed int, Derived2=thrust::device_ptr, Value2=signed int, System2=thrust ::device_system_tag, Traversal2=thrust::random_access_traversal_tag, Reference2=thrust::device_reference, Difference2=signed int]" 1> C:/ProgramData/NVIDIA Corporation/CUDA サンプル/v5.5/7_CUDALibraries/nsgaIIparallelo_23ott/rank_cuda.cu(70 ): ここDifference2=signed int]" 1> C:/ProgramData/NVIDIA Corporation/CUDA Samples/v5.5/7_CUDALibraries/nsgaIIparallelo_23ott/rank_cuda.cu(70): こちらDifference2=signed int]" 1> C:/ProgramData/NVIDIA Corporation/CUDA Samples/v5.5/7_CUDALibraries/nsgaIIparallelo_23ott/rank_cuda.cu(70): こちら
代わりに出力配列に Thrust::device_vector を使用すると、すべて問題ありません。
using namespace thrust;
thrust::device_vector<int> output(5);
float stencil[5];
stencil[0] = 0;
stencil[1] = 0;
stencil[2] = 1;
stencil[3] = 0;
stencil[4] = 1;
device_ptr<float> tp_stencil = device_pointer_cast(stencil);
device_vector<int>::iterator output_end = copy_if(make_counting_iterator<int>(0),
make_counting_iterator<int>(5),
tp_stencil,
output.begin(),
_1 == 1);
int number_of_ones = output_end - output.begin();
この問題の解決策を提案できますか? ありがとうございました。