Parallel processing CUDA中具有重复键的合并列表

Parallel processing CUDA中具有重复键的合并列表,parallel-processing,cuda,set,thrust,Parallel Processing,Cuda,Set,Thrust,假设我们有一个结构图节点列表*: struct graph_node{ int from; int to; float prob; } 现在,假设列表中重复了几个.from和.to元素。例如:我们可以有两个具有相同.from和.to属性(5,6,6)和(5,6,5)的节点 我想知道的是,在推力或cuda中是否有一种方法可以合并这两个元素并添加它们的概率(对于前面的示例,有5,6和1.1),或者只是添加包含相同的.from和.to的对象的所有概率,并将添加的概率分配给具有该键的所有元

假设我们有一个结构图节点列表*:

struct graph_node{
  int from;
  int to;
  float prob;
}
现在,假设列表中重复了几个.from和.to元素。例如:我们可以有两个具有相同.from和.to属性(5,6,6)和(5,6,5)的节点


我想知道的是,在推力或cuda中是否有一种方法可以合并这两个元素并添加它们的概率(对于前面的示例,有5,6和1.1),或者只是添加包含相同的.from和.to的对象的所有概率,并将添加的概率分配给具有该键的所有元素(5,6,1.1和5,6,1.1).

如@Talonmes在评论中所示,这可以通过使用来完成。首先,必须对
graph\u node
列表进行排序,以便将相似的节点聚集在一起。然后可以使用
reduce\u by_key
对类似节点求和

这方面可能有很多变化,具体取决于您实际愿意如何存储数据,以及是否允许修改输入列表等。我假设数据必须存储在您定义的结构的向量中,并且输出列表必须与输入列表分开

在这种情况下,我们需要为排序操作提供一个函子,以指示如何按排序顺序排列
graph\u节点。我们还需要为
reduce\u by\u key
操作提供相等测试和求和运算符。下面是一个完整的示例,展示了一种可能的方法:

$ cat t13.cu

#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/reduce.h>
#include <iostream>
#include <vector>
#include <thrust/host_vector.h>

struct graph_node{
  int from;
  int to;
  float prob;
};

struct my_graph_node_sort
{
  __host__ __device__
  bool operator()(graph_node &a, graph_node &b){
    if (a.from > b.from) return false;
    if (a.from < b.from) return true;
    return (a.to <= b.to);
  }
};

struct my_graph_node_equality
{
  __host__ __device__
  bool operator()(const graph_node &a, const graph_node &b){
    return ((a.from == b.from) && (a.to == b.to));
  }
};

struct my_graph_node_reduce
{
  __host__ __device__
  graph_node operator()(const graph_node &a, const graph_node &b){
    graph_node t = a;
    t.prob += b.prob;
    return t;
  }
};


int main(){

  std::vector<graph_node> h_n = { {0,1,0.1f}, {0,2,0.1f},{5,6,0.6f},{1,2,0.1f},{2,5,0.1f},{5,6, 0.5f}};
  thrust::device_vector<graph_node> d_n = h_n;
  thrust::device_vector<graph_node> d_kr(d_n.size());
  thrust::device_vector<graph_node> d_vr(d_n.size());
  thrust::sort(d_n.begin(), d_n.end(), my_graph_node_sort());
  int rs = (thrust::reduce_by_key(d_n.begin(), d_n.end(), d_n.begin(),d_kr.begin(), d_vr.begin(), my_graph_node_equality(), my_graph_node_reduce())).first - d_kr.begin();
  thrust::host_vector<graph_node> h_r = d_vr;
  std::cout << "from,to,prob" << std::endl;
  for (int i = 0; i < rs; i++)
    std::cout << h_r[i].from << "," << h_r[i].to << "," << h_r[i].prob << std::endl;
}
$ nvcc -std=c++11 -arch=sm_35 -o t13 t13.cu
$ ./t13
from,to,prob
0,1,0.1
0,2,0.1
1,2,0.1
2,5,0.1
5,6,1.1
$
$cat t13.cu
#包括
#包括
#包括
#包括
#包括
#包括
结构图节点{
int from;
int到;
浮动探针;
};
结构我的图节点排序
{
__主机设备__
布尔运算符()(图节点&a、图节点&b){
如果(a.from>b.from)返回false;
如果(a.from显然,有一种方法。听起来你是在试图描述一个按键减少,或是一个直方图的轻微修改。如果你想做一点研究的话,这两个问题都已经解决了