00001
00024 #ifndef AVI_UNORDERED_H_
00025 #define AVI_UNORDERED_H_
00026
00027
00028 #include "Galois/Graphs/Graph.h"
00029 #include "Galois/Galois.h"
00030
00031
00032 #include "Galois/Graphs/Serialize.h"
00033 #include "Galois/Graphs/FileGraph.h"
00034 #include "Galois/Runtime/PerCPU.h"
00035 #include "Galois/util/Atomic.h"
00036 #include "Galois/util/Accumulator.h"
00037
00038 #include "Lonestar/Banner.h"
00039 #include "Lonestar/CommandLine.h"
00040
00041 #include <string>
00042 #include <sstream>
00043 #include <limits>
00044 #include <iostream>
00045 #include <fstream>
00046 #include <set>
00047
00048 #include <cassert>
00049
00050 #include "AuxDefs.h"
00051 #include "AVI.h"
00052 #include "Element.h"
00053
00054 #include "AVIabstractMain.h"
00055
00078 class AVIunordered: public AVIabstractMain {
00079
00080 protected:
00081 typedef Galois::GAccumulator<int> IterCounter;
00082
00083 static const bool DEBUG = false;
00084
00085 static const int CHUNK_SIZE = 32;
00086
00087
00088 typedef Galois::Graph::FirstGraph<AVI*, void, false> Graph;
00089 typedef Graph::GraphNode GNode;
00090
00091 typedef GaloisRuntime::WorkList::ChunkedFIFO<CHUNK_SIZE, GNode> AVIWorkList;
00092
00093
00094 Graph graph;
00095
00096 virtual const std::string getVersion () const {
00097 return "Parallel Unordered";
00098 }
00099
00108 void genElemAdjGraph (const MeshInit& meshInit, const GlobalVec& g) {
00109 std::vector<GNode> aviAdjNodes;
00110
00111 const std::vector<AVI*>& aviList = meshInit.getAVIVec ();
00112
00113 for (std::vector<AVI*>::const_iterator i = aviList.begin (), e = aviList.end (); i != e; ++i) {
00114 AVI* avi = *i;
00115 GNode gn = graph.createNode (avi);
00116 graph.addNode (gn);
00117
00118 aviAdjNodes.push_back (gn);
00119 }
00120
00121
00122
00123
00124
00125
00126 std::vector< std::vector<GNode> > nodeSharers(meshInit.getNumNodes ());
00127
00128
00129
00130
00131
00132 for (std::vector<GNode>::const_iterator i = aviAdjNodes.begin (), ei = aviAdjNodes.end (); i != ei; ++i) {
00133 GNode aviAdjN = *i;
00134 AVI* avi = graph.getData (aviAdjN, Galois::NONE);
00135 const std::vector<GlobalNodalIndex>& conn = avi->getGeometry ().getConnectivity ();
00136
00137 for (std::vector<GlobalNodalIndex>::const_iterator j = conn.begin (), ej = conn.end (); j != ej; ++j) {
00138 GlobalNodalIndex n = *j;
00139 nodeSharers[n].push_back (aviAdjN);
00140 }
00141
00142 }
00143
00144 int numEdges = 0;
00145
00146 for (std::vector< std::vector<GNode> >::const_iterator it = nodeSharers.begin (), ei = nodeSharers.end ();
00147 it != ei; ++it) {
00148
00149 const std::vector<GNode>& adjElms = *it;
00150
00151
00152
00153 for (size_t i = 0; i < adjElms.size (); ++i) {
00154
00155 for (size_t j = i + 1; j < adjElms.size (); ++j) {
00156 if (!adjElms[i].hasNeighbor (adjElms[j])) {
00157 ++numEdges;
00158 }
00159 graph.addEdge (adjElms[i], adjElms[j]);
00160 }
00161 }
00162
00163 }
00164
00165 printf ("Graph created with %d nodes and %d edges\n", graph.size (), numEdges);
00166
00167 }
00168
00169
00170 virtual void initRemaining (const MeshInit& meshInit, const GlobalVec& g) {
00171 genElemAdjGraph (meshInit, g);
00172 }
00173
00175 struct process {
00176
00177 Graph& graph;
00178 std::vector<int>& inDegVec;
00179 MeshInit& meshInit;
00180 GlobalVec& g;
00181 GaloisRuntime::PerCPU<LocalVec>& perIterLocalVec;
00182 const AVIComparator& aviCmp;
00183 bool createSyncFiles;
00184 IterCounter& iter;
00185
00186 process (
00187 Graph& graph,
00188 std::vector<int>& inDegVec,
00189 MeshInit& meshInit,
00190 GlobalVec& g,
00191 GaloisRuntime::PerCPU<LocalVec>& perIterLocalVec,
00192 const AVIComparator& aviCmp,
00193 bool createSyncFiles,
00194 IterCounter& iter):
00195
00196 graph (graph),
00197 inDegVec (inDegVec),
00198 meshInit (meshInit),
00199 g (g),
00200 perIterLocalVec (perIterLocalVec),
00201 aviCmp (aviCmp),
00202 createSyncFiles (createSyncFiles),
00203 iter (iter) {}
00204
00205
00217 template <typename ContextTy>
00218 void operator () (const GNode& src, ContextTy& lwl) {
00219
00220
00221
00222 AVI* srcAVI = graph.getData (src, Galois::CHECK_CONFLICT);
00223
00224 for (Graph::neighbor_iterator j = graph.neighbor_begin (src, Galois::CHECK_CONFLICT)
00225 , ej = graph.neighbor_end (src, Galois::CHECK_CONFLICT); j != ej; ++j) {
00226 }
00227
00228
00229
00230
00231
00232 int inDeg = inDegVec[srcAVI->getGlobalIndex ()];
00233
00234
00235
00236
00237
00238 assert (inDeg == 0);
00239
00240
00241 LocalVec& l = perIterLocalVec.get();
00242
00243 AVIabstractMain::simulate(srcAVI, meshInit, g, l, createSyncFiles);
00244
00245
00246
00247
00248
00249 for (Graph::neighbor_iterator j = graph.neighbor_begin (src, Galois::NONE), ej = graph.neighbor_end (src, Galois::NONE);
00250 j != ej; ++j) {
00251
00252 const GNode& dst = *j;
00253 AVI* dstAVI = graph.getData (*j, Galois::NONE);
00254
00255 if (aviCmp.compare (srcAVI, dstAVI) > 0) {
00256
00257
00258 ++inDegVec[srcAVI->getGlobalIndex ()];
00259
00260 int din = (--inDegVec[dstAVI->getGlobalIndex ()] );
00261
00262 if (din == 0) {
00263
00264 if (dstAVI->getNextTimeStamp () < meshInit.getSimEndTime ()) {
00265 lwl.push (dst);
00266 }
00267 }
00268 }
00269
00270 }
00271
00272 if (inDegVec[srcAVI->getGlobalIndex ()] == 0) {
00273
00274 if (srcAVI->getNextTimeStamp () < meshInit.getSimEndTime ()) {
00275 lwl.push (src);
00276 }
00277 }
00278
00279
00280 ++ (iter.get ());
00281
00282
00283 }
00284 };
00285
00286 public:
00287
00288 virtual void runLoop (MeshInit& meshInit, GlobalVec& g, bool createSyncFiles) {
00290
00292 std::vector<int> inDegVec(meshInit.getNumElements (), 0);
00293
00294 std::vector<GNode> initWl;
00295
00296 AVIComparator aviCmp;
00297
00298 for (Graph::active_iterator i = graph.active_begin (), e = graph.active_end (); i != e; ++i) {
00299 const GNode& src = *i;
00300 AVI* srcAVI = graph.getData (src, Galois::NONE);
00301
00302
00303 for (Graph::neighbor_iterator n = graph.neighbor_begin (src, Galois::NONE),
00304 en= graph.neighbor_end (src, Galois::NONE); n != en; ++n) {
00305
00306 AVI* dstAVI = graph.getData (*n, Galois::NONE);
00307 if (aviCmp.compare (srcAVI, dstAVI) > 0) {
00308 ++inDegVec[srcAVI->getGlobalIndex ()];
00309 }
00310 }
00311
00312
00313 if (inDegVec[srcAVI->getGlobalIndex ()] == 0) {
00314 initWl.push_back (src);
00315 }
00316 }
00317
00318
00319
00320 printf ("Initial worklist contains %zd elements\n", initWl.size ());
00321
00322
00323
00324
00325
00326
00327
00328
00330
00332
00333
00334
00335
00336 size_t nrows = meshInit.getSpatialDim ();
00337 size_t ncols = meshInit.getNodesPerElem();
00338
00339 LocalVec l(nrows, ncols);
00340
00341 GaloisRuntime::PerCPU<LocalVec> perIterLocalVec (l);
00342
00343 IterCounter iter(0);
00344
00345 process p( graph, inDegVec, meshInit, g, perIterLocalVec, aviCmp, createSyncFiles, iter);
00346
00347
00348 Galois::for_each< AVIWorkList >(initWl.begin (), initWl.end (), p);
00349
00350
00351 printf ("iterations = %d\n", iter.get ());
00352
00353 }
00354
00355
00356
00357 };
00358
00359 #endif