c++ - multi item replacing in cuda thrust -
i have device vector a,b,c following.
a = [1,1,3,3,3,4,4,5,5] b = [1,3,5] c = [2,8,6]
so want replace each of b in corresponding element in c. eg:
- 1 replaced 2,
- 3 replaced 8,
- 5 replaced 6
so following result
result = [2,2,8,8,8,4,4,6,6]
how achieve in cuda thrust or way of implementing in cuda c++. found thrust::replace replaces single element @ once. since need replace huge amount of data, becomes bottleneck replace 1 @ time.
this can done efficiently first building map , applying custom functor queries map.
the example code following steps:
get largest element of
c
. assumes data sorted.create map vector of size
largest_element
. copy new values @ position of old ones.apply
mapper
functora
. functor readsnew_value
map vector. ifnew_value
not0
, value ina
replaced new value. assumesc
never contain0
. if can contain0
, must use condition, e.g. initialize map vector-1
, check ifnew_value != -1
#include <thrust/device_vector.h> #include <thrust/iterator/permutation_iterator.h> #include <thrust/copy.h> #include <thrust/for_each.h> #include <thrust/scatter.h> #include <iostream> #define printer(name) print(#name, (name)) template <template <typename...> class v, typename t, typename ...args> void print(const char* name, const v<t,args...> & v) { std::cout << name << ":\t"; thrust::copy(v.begin(), v.end(), std::ostream_iterator<t>(std::cout, "\t")); std::cout << std::endl; } template <typename t> struct mapper { mapper(thrust::device_ptr<const t> map) : map(map) { } __host__ __device__ void operator()(t& value) const { const t& new_value = map[value]; if (new_value) { value = new_value; } } thrust::device_ptr<const t> map; }; int main() { using namespace thrust::placeholders; int a[] = {1,1,3,3,3,4,4,5,5}; int b[] = {1,3,5}; int c[] = {2,8,6}; int size_data = sizeof(a)/sizeof(a[0]); int size_replace = sizeof(b)/sizeof(b[0]); // copy demo data gpu thrust::device_vector<int> d_a (a, a+size_data); thrust::device_vector<int> d_b (b, b+size_replace); thrust::device_vector<int> d_c (c, c+size_replace); printer(d_a); printer(d_b); printer(d_c); int largest_element = d_c.back(); thrust::device_vector<int> d_map(largest_element); thrust::scatter(d_c.begin(), d_c.end(), d_b.begin(), d_map.begin()); printer(d_map); thrust::for_each(d_a.begin(), d_a.end(), mapper<int>(d_map.data())); printer(d_a); return 0; }
output
d_a: 1 1 3 3 3 4 4 5 5 d_b: 1 3 5 d_c: 2 8 6 d_map: 0 2 0 8 0 6 d_a: 2 2 8 8 8 4 4 6 6
Comments
Post a Comment