1

以下の簡単なコードを検討してください。

thrust::device_vector<int> positions(6);
thrust::sequence(positions.begin(), positions.end());
thrust::pair<thrust::device_vector<int>::iterator, thrust::device_vector<int>::iterator > end;
//copyListOfNgramCounteachdoc contains: 0,1,1,1,1,3
end.first = copyListOfNgramCounteachdoc.begin();
end.second = positions.begin();
for(int i =0 ; i < numDocs; i++){
    end= thrust::unique_by_key(end.first, end.first + 3,end.second);
}

int length = end.first - copyListOfNgramCounteachdoc.begin() ;
cout<<"the value of end -s is: "<<length;
for(int i =0 ; i< length ; i++){
  cout<<copyListOfNgramCounteachdoc[i];
}

このコードの出力は0、1、1、3であると予想しました。ただし、出力は0、1、1です。誰かが私に欠けているものを教えてもらえますか?注:の内容copyListOfNgramCounteachdocは0、1、1、1、1、3です。また、のタイプはcopyListOfNgramCounteachdocですthrust::device_vector<int>

編集:

end.first = storeNcCounts.begin();
    end.second = storeCompactedPositions.begin();
    int indexToWriteForIndexesarr = 0;
    for(int i =0 ; i < numDocs; i++){
        iter = end.first;
        end = thrust::unique_by_key_copy(copyListOfNgramCounteachdoc.begin() + (i*numUniqueNgrams), copyListOfNgramCounteachdoc.begin()+(i*numUniqueNgrams)+ numUniqueNgrams,positions.begin() + (i*numUniqueNgrams),end.first,end.second);
        int numElementsCopied = (end.first - iter);
        endIndex = beginIndex + numElementsCopied - 1;
        storeBeginIndexEndIndexSCNCtoRead[indexToWriteForIndexesarr++] = beginIndex;
        storeBeginIndexEndIndexSCNCtoRead[indexToWriteForIndexesarr++] = endIndex;
        beginIndex = endIndex + 1;
    }
4

1 に答える 1

1

この場合に使用したいのは だと思いますがthrust::unique_by_key_copy、読み進めてください。

問題は、必要unique_by_keyがない限り、入力配列を更新しないことです。1最初の呼び出しの場合、入力配列を実際に圧縮することなく、返されたイテレータを前方に移動することによって、重複を削除するだけで一意のキーのシーケンスを返すことができます。

ループを次のように置き換えると、何が起こっているかがわかります。

end.first = copyListOfNgramCounteachdoc.begin();
end.second = positions.begin();
thrust::device_vector<int>::iterator iter;

for(int i =0 ; i < numDocs; i++){
  cout <<"before ";
  for(iter = end.first; iter != end.first+3; iter++) cout<<*iter;

  end = thrust::unique_by_key(end.first, end.first + 3,end.second);

  cout <<" after ";
  for(iter = copyListOfNgramCounteachdoc.begin(); iter != end.first; iter++) cout<<*iter;
  cout << endl;

  for(int i =0 ; i< 6; i++) cout<<copyListOfNgramCounteachdoc[i];
  cout << endl;
}

このコードでは、次の出力が得られます。

before 011 after 01
011223
before 122 after 0112
011223

copyListofNgramCounteachdocの値が変化していないことがわかります。これは有効な動作です。unique_by_key_copythenの代わりに使用した場合unique_by_key、Thrust は一意性を保証するために実際に値を圧縮する必要がありましたが、この場合は各シーケンスに値が 2 つしかないため、その必要はありません。ドキュメントは言う:

戻り値は、範囲 [first, new_last) 内の 2 つの連続する要素が等しくないような反復子 new_last です。範囲 [new_last, last) の反復子はすべて逆参照可能ですが、それらが指す要素は指定されていません。unique は安定しています。つまり、削除されない要素の相対的な順序は変更されません。

を使用するunique_by_key_copyと、Thrust は一意のキーと値を強制的にコピーすることになり (明らかにコストがかかります)、期待した動作が見られるはずです。

unique_by_keyところで、これをループではなく単一の呼び出しで実行できる場合は、そうすることをお勧めします。

于 2012-06-18T05:21:23.623 に答える