我在MPI“master”(等级0)中执行以下代码。因此,不会出现任何竞争条件。
//Create a set which orders the elements according to their size.
auto comp = [](const vector<int>& a, const vector<int>& b) -> bool
{
if (a.size() < b.size())
return true;
if (a.size() > b.size())
return false;
return a < b;
};
auto path = std::set <vector<int>, decltype(comp)> (comp);
//Create an instance of Dijkstra's algorithm and execute it.
Dijkstra<Graph, LengthMap> dijkstra_test(g,length);
dijkstra_test.run(s);
int size =0;
//Print the path the algorithm found.
for (Node v=t;v != s; v=dijkstra_test.predNode(v))
{
std::cout << g.id(v) << "<-";
++size;
}
cout << g.id(s) << endl;;
//Fill the path set with all edges between source s and sink t. These will be used as tasks for the slaves.
for (ListGraphBase::Arc v=dijkstra_test.predArc(t);s!=g.target(v); v=dijkstra_test.predArc(g.source(v)))
{
path.insert(vector<int>{g.id(v)});
}
适用于小型数据集,但对于较大的数据集,它会引发分段错误。路径的打印仍然正确执行。
[Laptop:03801] *** Process received signal ***
[Laptop:03801] Signal: Segmentation fault (11)
[Laptop:03801] Signal code: Address not mapped (1)
[Laptop:03801] Failing at address: 0x7f5665be2ff8
[Laptop:03801] [ 0] /usr/lib/libpthread.so.0(+0x10f00)[0x7f5687345f00]
[Laptop:03801] [ 1] ./main[0x4102da]
[Laptop:03801] [ 2] ./main[0x409e31]
[Laptop:03801] [ 3] ./main[0x40b0b8]
[Laptop:03801] [ 4] /usr/lib/libc.so.6(__libc_start_main+0xf1)[0x7f5686fb4741]
[Laptop:03801] [ 5] ./main[0x4094e9]
[Laptop:03801] *** End of error message ***
整个计划:
#include <limits>
#include <set>
#include <map>
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include "GraphElements.h"
#include "Graph.h"
#include "DijkstraShortestPathAlg.h"
#include "YenTopKShortestPathsAlg.h"
#include <sys/time.h>
#include <mpi.h>
#include <stdlib.h>
#include <lemon/concepts/digraph.h>
#include <lemon/smart_graph.h>
#include <lemon/list_graph.h>
#include <lemon/lgf_reader.h>
#include <lemon/dijkstra.h>
#include <lemon/path.h>
#include <lemon/bin_heap.h>
using namespace lemon;
//mpic++ main.cpp -o main Graph.cpp YenTopKShortestPathsAlg.cpp DijkstraShortestPathAlg.cpp -lemon
//mpirun -np 4 ./main
void run(int *argc, char ***argv )
{
//Initiate the program run time counter.
//Here starts the MPI block.
MPI_Init(argc, argv);
//Init the k for the number of paths
int k = 5;
//Init the rank of the MPI process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//Init the number of processes.
int nOSlaves;
MPI_Comm_size(MPI_COMM_WORLD, &nOSlaves);
//Define the Parameter types of the lemon libraries.
typedef lemon::ListGraph Graph;
typedef Graph::EdgeIt EdgeIt;
typedef Graph::Edge Edge;
typedef Graph::NodeIt NodeIt;
typedef Graph::Node Node;
typedef Graph::EdgeMap<int> LengthMap;
using lemon::INVALID;
//Initialize the test graph.
Graph g;
for(int i = 1; i<= 1070376; i++)
{
g.addNode();
}
LengthMap length(g);
string line;
ifstream file ("output.gr");
if (file.is_open())
{
string word;
while (getline (file,line) )
{
std::string::size_type sz;
file >> word;
int node1 = stoi(word, &sz);
file >> word;
int node2 = stoi(word, &sz);
file >> word;
int distance = stoi(word, &sz);
Edge edge = g.addEdge(g.nodeFromId(node1),g.nodeFromId(node2));
length[edge] = distance;
}
file.close();
}
else cout << "Unable to open file";
Node s = g.nodeFromId(10);
Node t = g.nodeFromId(200);
cout << "done adding graph, starting execution" << endl;
//If the process is a coordinator.
if(rank==0)
{
//Contains the shortest paths.
multimap<int,vector<int>> shortestPaths;
//Contains the already tried examples **Debug purpose**
vector<vector<int>> removedPaths;
//Contains the job of the currently running slaves at their index.
vector<int> runningTasks[nOSlaves];
//Create a set which orders the elements according to their size.
auto comp = [](const vector<int>& a, const vector<int>& b) -> bool
{
if (a.size() < b.size())
return true;
if (a.size() > b.size())
return false;
return a < b;
};
auto path = std::set <vector<int>, decltype(comp)> (comp);
//Create an instance of Dijkstra's algorithm and execute it.
Dijkstra<Graph, LengthMap> dijkstra_test(g,length);
dijkstra_test.run(s);
//Fill the path set with all edges between source s and sink t. These will be used as tasks for the slaves.
for (ListGraphBase::Arc v=dijkstra_test.predArc(t);s!=g.target(v); v=dijkstra_test.predArc(g.source(v)))
{
path.insert(vector<int>{g.id(v)});
}
MPI_Finalize();
}
int main(int argc, char **argv)
{
run(&argc,&argv);
}