Given two key-value lists, I am trying to combine the two sides by matching the keys and applying a function to the two values when the keys match. In my case I want to mult
I think two set intersections are required, as suggested in the first answer. The other solutions won't work, and it is just coincidence in the input data they produce correct result. For example, if the second (key,value) pair is removed from the left set, the computed result will be different while it shouldn't Here is the code:
$ cat inner_join.cu
#include
#include
#include
#include
int main()
{
int _Lkeys[] = {1, 4, 5, 6};
int _Lvals[] = {3, 1, 2, 1};
int _Rkeys[] = {1, 3, 4, 5, 6, 7};
int _Rvals[] = {2, 1, 1, 4, 1, 2};
size_t Lsize = sizeof(_Lkeys) / sizeof(int);
size_t Rsize = sizeof(_Rkeys) / sizeof(int);
thrust::device_vector Lkeys(_Lkeys, _Lkeys + Lsize);
thrust::device_vector Lvals(_Lvals, _Lvals + Lsize);
thrust::device_vector Rkeys(_Rkeys, _Rkeys + Rsize);
thrust::device_vector Rvals(_Rvals, _Rvals + Rsize);
std::size_t min_size = std::min(Lsize, Rsize);
thrust::device_vector result_keys(min_size);
thrust::device_vector result_Rvals(min_size);
thrust::device_vector result_Lvals(min_size);
// set intersection keys, and left set values
size_t intersection_size =
thrust::set_intersection_by_key(Lkeys.begin(), Lkeys.end(), Rkeys.begin(),
Rkeys.end(), Lvals.begin(),
result_keys.begin(), result_Lvals.begin())
.first -
result_keys.begin();
// set intersection keys, and right set values
thrust::set_intersection_by_key(Rkeys.begin(), Rkeys.end(), Lkeys.begin(),
Lkeys.end(), Rvals.begin(),
result_keys.begin(), result_Rvals.begin());
result_Lvals.resize(intersection_size);
result_keys.resize(intersection_size);
thrust::device_vector result_values(intersection_size);
// join left and right intersection values
thrust::transform(result_Lvals.begin(), result_Lvals.end(),
result_Rvals.begin(), result_values.begin(),
thrust::multiplies());
std::cout << "keys: ";
thrust::copy_n(result_keys.begin(), intersection_size,
std::ostream_iterator(std::cout, ","));
std::cout << std::endl << "vals: ";
thrust::copy_n(result_values.begin(), intersection_size,
std::ostream_iterator(std::cout, ","));
std::cout << std::endl;
}
output
$ nvcc inner_join.cu -run
keys: 1,4,5,6,
vals: 6,1,8,1,