通过键推力删除唯一的副本
thrust remove copy unique by key
我对执行以下操作的最佳方法有点困惑:
假设我有以下排序的键值对
(K:V) (0:.5)(0:.7)(0:.9) (1:.2) (1:.6) (1:.8)
等等..
我想删除复制每个键的最小值,这样我就会有 2 个结果
按键最小值
(0 : .5)(1 : .2)
剩余
(0 : .7)(0 : .9)(1 : .6)(1 : .8)
thrust::unique_by_key_copy 似乎能够通过键给我最小值,因为 (K:V) 已排序。但是我不确定如何删除从原始文件中选择的那些以获得剩余的。
非常感谢任何想法或建议
我相信有很多方法可以做到这一点。
一种可能的方法是使用 thrust::adjacent_difference
创建一个 "flag array"。
然后使用 thrust::copy_if
(模板版本)使用标志数组(作为模板)select 首先是结果 1 中您想要的元素,然后是结果 2 中您想要的元素(逻辑上使用标志数组的倒数)。
这是一个有效的例子:
$ cat t671.cu
#include <thrust/copy.h>
#include <thrust/adjacent_difference.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <iostream>
struct is_zero
{
__host__ __device__
bool operator()(const int s_val) const {
return (!s_val);}
};
struct is_not_zero
{
__host__ __device__
bool operator()(const int s_val) const {
return (s_val);}
};
int main(){
int keys[] = {0, 0, 0, 1, 1, 1 };
float vals[] = {0.5f, 0.7f, 0.9f, 0.2f, 0.6f, 0.8f };
int my_size = sizeof(keys)/sizeof(keys[0]);
thrust::host_vector<int> h_keys(keys, keys+my_size);
thrust::host_vector<float> h_vals(vals, vals+my_size);
thrust::device_vector<int> d_keys = h_keys;
thrust::device_vector<float> d_vals = h_vals;
thrust::device_vector<int> flags(my_size);
thrust::device_vector<int> d_keys1(my_size);
thrust::device_vector<float> d_vals1(my_size);
thrust::device_vector<int> d_keys2(my_size);
thrust::device_vector<float> d_vals2(my_size);
thrust::adjacent_difference(d_keys.begin(), d_keys.end(), flags.begin());
flags[0] = 1; // first element is always included
int len1 = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_keys.begin(), d_vals.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_keys.end(), d_vals.end())), flags.begin(), thrust::make_zip_iterator(thrust::make_tuple(d_keys1.begin(), d_vals1.begin())), is_zero()) - thrust::make_zip_iterator(thrust::make_tuple(d_keys1.begin(), d_vals1.begin()));
int len2 = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_keys.begin(), d_vals.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_keys.end(), d_vals.end())), flags.begin(), thrust::make_zip_iterator(thrust::make_tuple(d_keys2.begin(), d_vals2.begin())), is_not_zero()) - thrust::make_zip_iterator(thrust::make_tuple(d_keys2.begin(), d_vals2.begin()));
thrust::host_vector<int> h_keys1(len1);
thrust::host_vector<float> h_vals1(len1);
thrust::copy_n(d_keys1.begin(), len1, h_keys1.begin());
thrust::copy_n(d_vals1.begin(), len1, h_vals1.begin());
thrust::host_vector<int> h_keys2(len2);
thrust::host_vector<float> h_vals2(len2);
thrust::copy_n(d_keys2.begin(), len2, h_keys2.begin());
thrust::copy_n(d_vals2.begin(), len2, h_vals2.begin());
std::cout << std::endl << "Input keys:" << std::endl;
thrust::copy(h_keys.begin(), h_keys.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Input values:" << std::endl;
thrust::copy(h_vals.begin(), h_vals.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "Output keys 1:" << std::endl;
thrust::copy(h_keys1.begin(), h_keys1.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Output values 1:" << std::endl;
thrust::copy(h_vals1.begin(), h_vals1.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "Output keys 2:" << std::endl;
thrust::copy(h_keys2.begin(), h_keys2.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Output values 2:" << std::endl;
thrust::copy(h_vals2.begin(), h_vals2.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
return 0;
}
$ nvcc -arch=sm_20 -o t671 t671.cu
$ ./t671
Input keys:
0,0,0,1,1,1,
Input values:
0.5,0.7,0.9,0.2,0.6,0.8,
Output keys 1:
0,0,1,1,
Output values 1:
0.7,0.9,0.6,0.8,
Output keys 2:
0,1,
Output values 2:
0.5,0.2,
$
我对执行以下操作的最佳方法有点困惑:
假设我有以下排序的键值对
(K:V) (0:.5)(0:.7)(0:.9) (1:.2) (1:.6) (1:.8)
等等..
我想删除复制每个键的最小值,这样我就会有 2 个结果
按键最小值
(0 : .5)(1 : .2)
剩余
(0 : .7)(0 : .9)(1 : .6)(1 : .8)
thrust::unique_by_key_copy 似乎能够通过键给我最小值,因为 (K:V) 已排序。但是我不确定如何删除从原始文件中选择的那些以获得剩余的。
非常感谢任何想法或建议
我相信有很多方法可以做到这一点。
一种可能的方法是使用 thrust::adjacent_difference
创建一个 "flag array"。
然后使用 thrust::copy_if
(模板版本)使用标志数组(作为模板)select 首先是结果 1 中您想要的元素,然后是结果 2 中您想要的元素(逻辑上使用标志数组的倒数)。
这是一个有效的例子:
$ cat t671.cu
#include <thrust/copy.h>
#include <thrust/adjacent_difference.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <iostream>
struct is_zero
{
__host__ __device__
bool operator()(const int s_val) const {
return (!s_val);}
};
struct is_not_zero
{
__host__ __device__
bool operator()(const int s_val) const {
return (s_val);}
};
int main(){
int keys[] = {0, 0, 0, 1, 1, 1 };
float vals[] = {0.5f, 0.7f, 0.9f, 0.2f, 0.6f, 0.8f };
int my_size = sizeof(keys)/sizeof(keys[0]);
thrust::host_vector<int> h_keys(keys, keys+my_size);
thrust::host_vector<float> h_vals(vals, vals+my_size);
thrust::device_vector<int> d_keys = h_keys;
thrust::device_vector<float> d_vals = h_vals;
thrust::device_vector<int> flags(my_size);
thrust::device_vector<int> d_keys1(my_size);
thrust::device_vector<float> d_vals1(my_size);
thrust::device_vector<int> d_keys2(my_size);
thrust::device_vector<float> d_vals2(my_size);
thrust::adjacent_difference(d_keys.begin(), d_keys.end(), flags.begin());
flags[0] = 1; // first element is always included
int len1 = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_keys.begin(), d_vals.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_keys.end(), d_vals.end())), flags.begin(), thrust::make_zip_iterator(thrust::make_tuple(d_keys1.begin(), d_vals1.begin())), is_zero()) - thrust::make_zip_iterator(thrust::make_tuple(d_keys1.begin(), d_vals1.begin()));
int len2 = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_keys.begin(), d_vals.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_keys.end(), d_vals.end())), flags.begin(), thrust::make_zip_iterator(thrust::make_tuple(d_keys2.begin(), d_vals2.begin())), is_not_zero()) - thrust::make_zip_iterator(thrust::make_tuple(d_keys2.begin(), d_vals2.begin()));
thrust::host_vector<int> h_keys1(len1);
thrust::host_vector<float> h_vals1(len1);
thrust::copy_n(d_keys1.begin(), len1, h_keys1.begin());
thrust::copy_n(d_vals1.begin(), len1, h_vals1.begin());
thrust::host_vector<int> h_keys2(len2);
thrust::host_vector<float> h_vals2(len2);
thrust::copy_n(d_keys2.begin(), len2, h_keys2.begin());
thrust::copy_n(d_vals2.begin(), len2, h_vals2.begin());
std::cout << std::endl << "Input keys:" << std::endl;
thrust::copy(h_keys.begin(), h_keys.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Input values:" << std::endl;
thrust::copy(h_vals.begin(), h_vals.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "Output keys 1:" << std::endl;
thrust::copy(h_keys1.begin(), h_keys1.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Output values 1:" << std::endl;
thrust::copy(h_vals1.begin(), h_vals1.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "Output keys 2:" << std::endl;
thrust::copy(h_keys2.begin(), h_keys2.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl << "Output values 2:" << std::endl;
thrust::copy(h_vals2.begin(), h_vals2.end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
return 0;
}
$ nvcc -arch=sm_20 -o t671 t671.cu
$ ./t671
Input keys:
0,0,0,1,1,1,
Input values:
0.5,0.7,0.9,0.2,0.6,0.8,
Output keys 1:
0,0,1,1,
Output values 1:
0.7,0.9,0.6,0.8,
Output keys 2:
0,1,
Output values 2:
0.5,0.2,
$