【发布时间】:2019-01-17 19:07:52
【问题描述】:
我正在尝试在 GPU 上运行 Brandes 算法(基本上是带有一些额外操作和数据结构的 bfs),并且我正在为每个线程分配一个顶点来运行 Brandes。我面临的问题是在我的代码中
我需要存储在 bfs 期间访问的每个顶点的父节点
。在 CPU 实现中,只要我找到一个技术上是动态扩展数组的新父对象,就可以通过创建向量映射并调用 push_back 来轻松实现。我不知道如何在 CUDA 中做到这一点。
这是我需要的功能的示例代码:
vector<int> distance; //Initialized to 0
vector<int> paths; //Initialized to 0
vector<bool> visited; //Initialized to false
map <int, vector<int> > parents; //Parent vector of each key is empty
queue<int> q;
// Running bfs from vertex
q.push(vertex);
while(!q.empty())
{
int source = q.front();
q.pop();
for(auto neighbour : adjacency_list[source])
{
if(!visited[neighbour])
{
visited[neighbour] = true;
q.push(neighbour);
distance[neighbour] = distance[source] + 1;
}
if(distance[neighbour] == distance[source] + 1)
{
paths[neighbour] += paths[source];
parents[neighbour].push_back(source);
}
}
}
{
// Use data accumulated above for calculations
....
}
这是我在设备代码中难以实现的行(功能)
父母[邻居].push_back(source);
我的印象:
我可以为每个顶点过度分配(最大程度的图形)父列表,但这会花费我很多未使用的内存
-
将父关系存储为大小为 2*Edges 的数组中的边,但我需要一个顶点的所有父级一起(连续存储或存储在同一容器中),这在此实现中是不可能的
李> 我知道 gpu 堆内存,但想不出一种方法来利用它供我使用
最坏的情况:我首先运行一个 bfs 来发现没有。每个顶点的父节点,然后为每个顶点分配适当的内存,然后再次运行品牌。
【问题讨论】:
-
我认为
cuda标签上可能已经存在各种可能性。例如,here 是多线程设备push_back操作的示例。它确实需要您为向量预先分配空间,但它不需要为每个线程分配空间,因此您可以根据所有线程或整个图形的需要过度分配。在其中构建溢出检测器也很容易。 -
@RobertCrovella 我阅读了链接中的代码,这与我的第二印象非常相似,即我可以将它们(父子对)全部存储在一个数组中,但我必须排序(在将它们用于下一部分代码之前,将顶点的所有父级对齐)。我希望我的问题让大家更清楚
标签: algorithm c++11 graph cuda