我在对使用推力:: make_zip_iterator(推力:: make_tuple())类型语法构造的zip_iterator上使用推力::反向功能时遇到奇怪的行为(请参阅JackOLantern的答案以了解很好的例子。
我希望反转多个设备向量的任意指示部分,如下面的示例代码所示。当我通过将它们捆绑在一起并将它们压缩在一起来进行一次反转时,会发生意外的行为。范围的前半部分已正确更改为范围的后半部分的倒置,但是范围的后半部分保持不变。
我一直在以类似的方式使用其他推力函数(sort_by_key,uniqe_by_key,neighbord_difference等),没有问题。我是在错误地执行此操作吗?还是出于某种原因,这在根本上不起作用?我的想法是,zip_iterator可能不是反向所需的双向。这是真的?我找不到这样的文档。
一种解决方法是单独反转向量,如下所示。但是,我怀疑这会降低效率。请注意,在我的实际用例中,我有大小为10,000的向量,并且正在将3-7个向量压缩到任意位置以进行操作。
#include <iostream>
#include <ostream>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/tuple.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/sequence.h>
#include <thrust/reverse.h>
int main(){
// initial host vectors
const int N=10;
thrust::host_vector<int> h1(N);
thrust::host_vector<float> h2(N);
// fill them
thrust::sequence( h1.begin(), h1.end(), 0);
thrust::sequence( h2.begin(), h2.end(), 10., 0.5);
// print initial contents
for (size_t i=0; i<N; i++){
std::cout << h1[i] << " " << h2[i] << std::endl;
}
// transfer to device
thrust::device_vector<int> d1 = h1;
thrust::device_vector<float> d2 = h2;
// what chunk to invert
int iStart = 3; int iEnd = 8;
// attempt to reverse middle via zip_iterators
thrust::reverse(
thrust::make_zip_iterator( thrust::make_tuple( d1.begin()+iStart, d2.begin()+iStart)),
thrust::make_zip_iterator( thrust::make_tuple( d1.begin()+iEnd, d2.begin()+iEnd))
);
// pull back and write out unexpected ordering
thrust::host_vector<int> temp1 = d1;
thrust::host_vector<float> temp2 = d2;
std::cout << "<==========>" << std::endl;
for (size_t i=0; i<N; i++){
std::cout << temp1[i] << " " << temp2[i] << std::endl;
}
// reset device variables
d1 = h1;
d2 = h2;
// reverse individually
thrust::reverse( d1.begin()+iStart, d1.begin()+iEnd);
thrust::reverse( d2.begin()+iStart, d2.begin()+iEnd);
// pull back and write out the desired ordering
temp1 = d1;
temp2 = d2;
std::cout << "<==========>" << std::endl;
for (size_t i=0; i<N; i++){
std::cout << temp1[i] << " " << temp2[i] << std::endl;
}
return 0;
}
输出
0 10
1 10.5
2 11
3 11.5
4 12
5 12.5
6 13
7 13.5
8 14
9 14.5
<==========>
0 10
1 10.5
2 11
7 13.5
6 13
5 12.5
6 13
7 13.5
8 14
9 14.5
<==========>
0 10
1 10.5
2 11
7 13.5
6 13
5 12.5
4 12
3 11.5
8 14
9 14.5
答案 0 :(得分:0)
Robert Crovella在评论中提供的信息以及初始帖子中最初给出的解决方法似乎可以回答问题-因此,我将在此处将其合并,以便可以将问题标记为“已回答”。如果其他人希望发布其他解决方案,我很乐意查看它们并移动“官方回答”复选标记。话虽这么说...
问题的解决方案包括两个部分:
如果无法升级到较新版本的CUDA:分别对向量应用反向,以实现与初始文章中给出的相同结果。为了完整起见,下面仅复制了具有工作解决方案的代码。
data2 %>%
group_by(add) %>% # for each add value
mutate(group2 = rleid(group)) %>% # created group2
filter(group=="male" & group2==3) %>% # keep only male after female
summarise(SUM = sum(x1[row_number() <= 4])) # get sum of x1 for first 4 rows
# # A tibble: 2 x 2
# add SUM
# <fct> <dbl>
# 1 x 94.9
# 2 y 107.