Combining two lists by key using Thrust

后端 未结 3 1334
广开言路
广开言路 2020-12-04 00:25

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

3条回答
  •  粉色の甜心
    2020-12-04 01:00

    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,
    

提交回复
热议问题