c++ - CUDA Thrust - How can I write a function using multiple device vectors with different sizes? -
i've been trying figure out how perform simple entropy calculation using 4 thrust device vectors.
i have 4 device vectors, representing 2 key-value pairs. first pair of vectors contains keys , number of times key appears. second pair contains keys paired bins calculating entropy. in second vector pair, keys appear multiple times, each instance representing different bin.
it looks this:
device vector pair 1
keyval 6 8 9
counts 1 3 2
device vector pair 2
keyval 6 8 8 9 9
binval 1 1 2 1 1
result vector (contains calculated entropy results)
keyval 8
entropy 0.602
what i'm planning on doing use first vector pair check if key appears enough times calculate entropy. if count large enough, second vector pair used calculate entropy bin values key. need use of bin values particular key. example, if wanted calculate entropy keys have appeared @ least 3 times, find in first vector pair keyval 8 ready. then, search second pair instances of keyval 8, , calculate entropy using corresponding binvals. entropy calculation simple, involves adding binval*log(binval) each relevant value. in example, entropy = 1*log(1) + 2*log(2).
however, have no clue how make part work. i've tried using thrust::for_each find keys appear enough times tested, don't think it's possible search keys in second vector pair , perform calculation within for_each function.
does have suggestions on other ways accomplish this?
thank help.
the 2 ideas considered were:
idea a:
- compute entropies
- select ones meet criteria
idea b:
- select incoming data meets criteria
- compute entropies.
idea seems doing unnecessary work - computing entropies or may not needed. worked through process idea b, ended adding many steps (such computing prefix sums) complete step 1 of idea b, did not seem better. present idea now. maybe m.s. or else come along , post better.
step 1 of idea handled thrust::reduce_by_key
along appropriate functor compute specific entropy function
step 2 of idea handled thrust::copy_if
$ cat t827.cu #include <iostream> #include <thrust/device_vector.h> #include <thrust/copy.h> #include <thrust/reduce.h> #include <thrust/iterator/zip_iterator.h> #include <thrust/iterator/transform_iterator.h> #include <thrust/iterator/discard_iterator.h> #include <math.h> // thresh determines minimum counts value required keyval entropy calculation occur #define thresh 2 using namespace thrust::placeholders; struct my_entropy : public thrust::unary_function<float, float> { __host__ __device__ float operator()(float val){ return val*log10f(val);} // if want napierian log, change logf }; int main(){ int keyval1[]={6, 8, 9}; int counts[] ={1, 3, 2}; int keyval2[]={6, 8, 8, 9, 9}; float binval[] ={1, 1, 2, 1, 1}; int dsize1 = sizeof(keyval1)/sizeof(int); int dsize2 = sizeof(keyval2)/sizeof(int); thrust::device_vector<int> d_keyval1(keyval1, keyval1+dsize1); thrust::device_vector<int> d_counts(counts, counts+dsize1); thrust::device_vector<int> d_keyval2(keyval2, keyval2+dsize2); thrust::device_vector<float> d_binval(binval, binval+dsize2); // method 1 - compute entropies, select desired ones thrust::device_vector<float> entropies(dsize2); thrust::reduce_by_key(d_keyval2.begin(), d_keyval2.end(), thrust::make_transform_iterator(d_binval.begin(), my_entropy()), thrust::make_discard_iterator(), entropies.begin()); thrust::device_vector<int> res_keys(dsize1); thrust::device_vector<float>res_ent(dsize1); int res_size = thrust::copy_if(thrust::make_zip_iterator(thrust::make_tuple(d_keyval1.begin(), entropies.begin())), thrust::make_zip_iterator(thrust::make_tuple(d_keyval1.end(), entropies.end())), d_counts.begin(), thrust::make_zip_iterator(thrust::make_tuple(res_keys.begin(), res_ent.begin())), _1 >= thresh) - thrust::make_zip_iterator(thrust::make_tuple(res_keys.begin(), res_ent.begin())); std::cout << "counts threshold: " << thresh << std::endl << "selected keys: " << std::endl; thrust::copy_n(res_keys.begin(), res_size, std::ostream_iterator<int>(std::cout, ",")); std::cout << std::endl << "calculated entropies: " << std::endl; thrust::copy_n(res_ent.begin(), res_size, std::ostream_iterator<float>(std::cout, ",")); std::cout << std::endl; return 0; } [bob@cluster1 misc]$ nvcc -o t827 t827.cu $ ./t827 counts threshold: 2 selected keys: 8,9, calculated entropies: 0.60206,0, $
Comments
Post a Comment