如何在推力集操作中动态设置device_vectors的大小?
How to dynamically set the size of device_vectors in thrust set operations?
我有两组 A 和 B。我的操作结果 (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
。在实际问题中,我不知道 result 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;
}
在一般情况下(即跨各种推力算法)通常没有办法知道输出大小,除了上限是多少。这里通常的方法是传递一个结果向量,其大小是可能输出大小的上限。正如您已经说过的,在许多情况下,无法先验地知道输出的实际大小。 Thrust 没有特别的魔法来解决这个问题。操作后,您将知道结果的大小,如果 "extra zeroes" 由于某种原因出现问题(我想不出它们会成为问题的原因),则可以将其复制到新向量一般来说,除了他们用完分配的 space).
如果这是非常令人反感的,一种可能性(从 Jared Hoberock 在 another forum) is to run the algorithm twice, the first time using a discard_iterator
的响应中复制此信息(对于输出数据),第二次使用真正的迭代器,指向实际的向量分配, 必要的大小。在第一遍中,discard_iterator
用于计算实际结果数据的大小,即使它没有存储在任何地方。直接引用 Jared 的话:
在第一阶段,传递一个discard_iterator
作为输出迭代器。您可以比较作为结果返回的 discard_iterator
来计算输出的大小。在第二阶段,调用算法 "for real" 并输出到使用第一阶段结果确定大小的数组中。
该技术在 set_operations.cu 示例 [0,1]:
中进行了演示
[0] https://github.com/thrust/thrust/blob/master/examples/set_operations.cu#L25
[1] https://github.com/thrust/thrust/blob/master/examples/set_operations.cu#L127
thrust::set_difference
returns 指向结果范围末尾的迭代器。
如果您只想将 C 的逻辑大小更改为结果元素的数量,您可以简单地擦除范围 "behind" 结果范围。
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());
}
我有两组 A 和 B。我的操作结果 (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
。在实际问题中,我不知道 result 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;
}
在一般情况下(即跨各种推力算法)通常没有办法知道输出大小,除了上限是多少。这里通常的方法是传递一个结果向量,其大小是可能输出大小的上限。正如您已经说过的,在许多情况下,无法先验地知道输出的实际大小。 Thrust 没有特别的魔法来解决这个问题。操作后,您将知道结果的大小,如果 "extra zeroes" 由于某种原因出现问题(我想不出它们会成为问题的原因),则可以将其复制到新向量一般来说,除了他们用完分配的 space).
如果这是非常令人反感的,一种可能性(从 Jared Hoberock 在 another forum) is to run the algorithm twice, the first time using a discard_iterator
的响应中复制此信息(对于输出数据),第二次使用真正的迭代器,指向实际的向量分配, 必要的大小。在第一遍中,discard_iterator
用于计算实际结果数据的大小,即使它没有存储在任何地方。直接引用 Jared 的话:
在第一阶段,传递一个discard_iterator
作为输出迭代器。您可以比较作为结果返回的 discard_iterator
来计算输出的大小。在第二阶段,调用算法 "for real" 并输出到使用第一阶段结果确定大小的数组中。
该技术在 set_operations.cu 示例 [0,1]:
中进行了演示[0] https://github.com/thrust/thrust/blob/master/examples/set_operations.cu#L25
[1] https://github.com/thrust/thrust/blob/master/examples/set_operations.cu#L127
thrust::set_difference
returns 指向结果范围末尾的迭代器。
如果您只想将 C 的逻辑大小更改为结果元素的数量,您可以简单地擦除范围 "behind" 结果范围。
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());
}