我有两组A和B。我的运算的result(C)应该具有A中的元素,而元素不在B中。我使用set_difference来做到这一点。但是,必须在操作前设置result(C)的大小。否则它的末尾会有额外的零,如下所示:
A=
1 2 3 4 5 6 7 8 9 10
B=
1 2 8 11 7 4
C=
3 5 6 9 10 0 0 0 0 0
如何动态设置result(C)的大小,以便输出为C= 3 5 6 9
。在实际问题中,我不知道结果device_vector apriori的要求大小。
我的代码:
#include <thrust/execution_policy.h>
#include <thrust/set_operations.h>
#include <thrust/sequence.h>
#include <thrust/execution_policy.h>
#include <thrust/device_vector.h>
void remove_common_elements(thrust::device_vector<int> A, thrust::device_vector<int> B, thrust::device_vector<int>& C)
{
thrust::sort(thrust::device, A.begin(), A.end());
thrust::sort(thrust::device, B.begin(), B.end());
thrust::set_difference(thrust::device, A.begin(), A.end(), B.begin(), B.end(), C.begin());
}
int main(int argc, char * argv[])
{
thrust::device_vector<int> A(10);
thrust::sequence(thrust::device, A.begin(), A.end(),1); // x components of the 'A' vectors
thrust::device_vector<int> B(6);
B[0]=1;B[1]=2;B[2]=8;B[3]=11;B[4]=7;B[5]=4;
thrust::device_vector<int> C(A.size());
std::cout << "A="<< std::endl;
thrust::copy(A.begin(), A.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::cout << "B="<< std::endl;
thrust::copy(B.begin(), B.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
remove_common_elements(A, B, C);
std::cout << "C="<< std::endl;
thrust::copy(C.begin(), C.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
答案 0 :(得分:2)
在一般情况下(即,在各种推力算法中),通常没有办法知道输出大小,除非上限是多少。此处通常的方法是传递结果向量,其大小为可能的输出大小的上限。正如您已经说过的,在许多情况下,先验输出的实际大小是未知的。推力没有特别的魔术来解决这个问题。运算后,您将知道结果的大小,如果由于某些原因“多余的零”成为问题,则可以将结果复制到新的向量中(我不认为它们通常会成为问题的原因,但它们会用完分配的空间。
如果这是非常令人反感的,则一种可能性(从Jared Hoberock在another forum中的响应中复制此信息)是运行算法两次,这是第一次使用{{3 }}(用于输出数据),第二次使用真正的迭代器,指向实际的矢量分配,其大小是必需的。在第一遍期间,discard_iterator
用于计数实际结果数据的大小,即使它没有存储在任何地方。直接从Jared报价:
在第一阶段,传递一个discard_iterator
作为输出迭代器。您可以比较作为结果返回的discard_iterator
,以计算输出的大小。在第二阶段,将算法称为“真实”算法,并输出到使用第一阶段结果确定大小的数组。
该技术在set_operations.cu示例[0,1]中进行了演示:
[0] discard_iterator
[1] https://github.com/thrust/thrust/blob/master/examples/set_operations.cu#L25
答案 1 :(得分:1)
thrust::set_difference
将迭代器返回到结果范围的末尾。
如果只想将C的逻辑大小更改为结果元素的数量,则可以简单地擦除结果范围“后面”的范围。
void remove_common_elements(thrust::device_vector<int> A,
thrust::device_vector<int> B, thrust::device_vector<int>& C)
{
thrust::sort(thrust::device, A.begin(), A.end());
thrust::sort(thrust::device, B.begin(), B.end());
auto C_end = thrust::set_difference(thrust::device, A.begin(), A.end(), B.begin(), B.end(), C.begin());
C.erase(C_end, C.end());
}