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没有改变。这是有效的行为。如果您使用Thrustunique_by_key_copy而不是unique_by_keythen 将被迫实际压缩值以保证唯一性,但在这种情况下,由于每个序列中只有两个值,因此没有必要。文档说:

返回值是一个迭代器 new_last 使得 [first, new_last) 范围内没有两个连续元素相等。[new_last, last) 范围内的迭代器仍然是可解引用的,但它们指向的元素是未指定的。unique 是稳定的,这意味着没有被移除的元素的相对顺序是不变的。

如果您使用unique_by_key_copy,则 Thrust 将被迫复制唯一的键和值(具有明显的成本影响),您应该会看到您所期望的行为。

顺便说一句,如果您可以在一次调用中执行此操作,unique_by_key而不是在循环中执行,我建议您这样做。

于 2012-06-18T05:21:23.623 回答