00001 
00055 #ifndef GALOIS_GRAPHS_FILEGRAPH_H
00056 #define GALOIS_GRAPHS_FILEGRAPH_H
00057 
00058 
00059 #include "Galois/Graphs/Graph.h"
00060 #include <boost/iterator/counting_iterator.hpp>
00061 
00062 using namespace GaloisRuntime;
00063 
00064 namespace Galois {
00065 namespace Graph {
00066 
00068 class FileGraph {
00069 public:
00070   typedef uint32_t GraphNode;
00071 
00072 protected:
00073   void* masterMapping;
00074   size_t masterLength;
00075   uint64_t sizeEdgeTy;
00076   int masterFD;
00077 
00078   uint64_t* outIdx;
00079   uint32_t* outs;
00080 
00081   char* edgeData;
00082 
00083   uint64_t numEdges;
00084   uint64_t numNodes;
00085 
00086   uint64_t getEdgeIdx(GraphNode src, GraphNode dst) {
00087     for (neighbor_iterator ii = neighbor_begin(src),
00088            ee = neighbor_end(src); ii != ee; ++ii)
00089       if (*ii == dst)
00090         return std::distance(outs, ii);
00091     return ~(uint64_t)0;
00092   }
00093 
00094 public:
00095   
00096 
00098   bool containsNode(const GraphNode n) {
00099     return n < numNodes;
00100   }
00101 
00102   
00103   template<typename EdgeTy>
00104   EdgeTy& getEdgeData(GraphNode src, GraphNode dst, MethodFlag mflag = ALL) {
00105     assert(sizeEdgeTy == sizeof(EdgeTy));
00106     return ((EdgeTy*)edgeData)[getEdgeIdx(src,dst)];
00107   }
00108 
00109   void prefetch_edges(GraphNode N) {
00110     __builtin_prefetch(neighbor_begin(N, NONE));
00111   }
00112 
00113   template<typename EdgeTy>
00114   void prefetch_edgedata(GraphNode N) {
00115     __builtin_prefetch(
00116         &((EdgeTy*)edgeData)[std::distance(outs, neighbor_begin(N))]);
00117   }
00118 
00119   void prefetch_pre(GraphNode N) {
00120     if (N != 0)
00121       __builtin_prefetch(&outIdx[N-1]);
00122     __builtin_prefetch(&outIdx[N]);
00123   }
00124 
00125   
00126 
00127   typedef uint32_t* neighbor_iterator;
00128 
00129   neighbor_iterator neighbor_begin(GraphNode N, MethodFlag mflag = ALL) {
00130     if (N == 0)
00131       return &outs[0];
00132     else
00133       return &outs[outIdx[N-1]];
00134   }
00135 
00136   neighbor_iterator neighbor_end(GraphNode N, MethodFlag mflag = ALL) {
00137     return &outs[outIdx[N]];
00138   }
00139 
00140   bool has_neighbor(GraphNode N1, GraphNode N2, MethodFlag mflag = ALL) {
00141     return std::find(neighbor_begin(N1), neighbor_end(N1), N2) != neighbor_end(N1);
00142   }
00143 
00144   typedef boost::counting_iterator<uint64_t> active_iterator;
00145 
00147   active_iterator active_begin() {
00148     return active_iterator(0);
00149   }
00150 
00151   active_iterator active_end() {
00152     return active_iterator(numNodes);
00153   }
00154 
00156   unsigned int size() {
00157     return numNodes;
00158   }
00159 
00160   FileGraph();
00161   ~FileGraph();
00162 
00164   bool structureFromFile(const char* filename);
00165 };
00166 
00168 template<typename NodeTy, typename EdgeTy>
00169 class LC_FileGraph : public FileGraph {
00170 
00171   struct gNode : public GaloisRuntime::Lockable {
00172     NodeTy data;
00173     gNode() {}
00174   };
00175 
00176   
00177   cache_line_storage<gNode>* NodeData;
00178 
00179 public:
00180   LC_FileGraph() :NodeData(0) {}
00181   ~LC_FileGraph() {
00182     if (NodeData)
00183       delete[] NodeData;
00184   }
00185   
00186   NodeTy& getData(GraphNode N, MethodFlag mflag = ALL) {
00187     GaloisRuntime::acquire(&NodeData[N].data, mflag);
00188     return NodeData[N].data.data;
00189   }
00190 
00191   EdgeTy& getEdgeData(GraphNode src, GraphNode dst, MethodFlag mflag = ALL) {
00192     return FileGraph::getEdgeData<EdgeTy>(src, dst, mflag);
00193   }
00194 
00196   void nodeDataFromFile(const char* filename) {
00197     emptyNodeData();
00198     std::ifstream file(filename);
00199     for (uint64_t i = 0; i < numNodes; ++i)
00200       file >> NodeData[i];
00201   }
00202   
00204   void emptyNodeData(NodeTy init = NodeTy()) {
00205     NodeData = new cache_line_storage<gNode>[numNodes];
00206     for (uint64_t i = 0; i < numNodes; ++i)
00207       NodeData[i].data.data = init;
00208   }
00209 
00210   void prefetch_edgedata(GraphNode N) {
00211     FileGraph::prefetch_edgedata<EdgeTy>(N);
00212   }
00213 
00214   void prefetch_neighbors(GraphNode N) {
00215     for (neighbor_iterator ii = neighbor_begin(N, NONE),
00216         ee = neighbor_begin(N,NONE); ii != ee; ++ii)
00217       __builtin_prefetch(&NodeData[*ii].data.data);
00218   }
00219 
00220 };
00221 
00222 template<typename NodeTy>
00223 class LC_FileGraph<NodeTy, void>: public FileGraph { 
00224 
00225   struct gNode : public GaloisRuntime::Lockable {
00226     NodeTy data;
00227     gNode() {}
00228   };
00229 
00230   
00231   cache_line_storage<gNode>* NodeData;
00232 
00233 public:
00234   LC_FileGraph() :NodeData(0) {}
00235   ~LC_FileGraph() {
00236     if (NodeData)
00237       delete[] NodeData;
00238   }
00239   
00240   NodeTy& getData(GraphNode N, MethodFlag mflag = ALL) {
00241     GaloisRuntime::acquire(&NodeData[N].data, mflag);
00242     return NodeData[N].data.data;
00243   }
00244 
00245   void nodeDataFromFile(const char* filename) {
00246     emptyNodeData();
00247     std::ifstream file(filename);
00248     for (uint64_t i = 0; i < numNodes; ++i)
00249       file >> NodeData[i];
00250   }
00251   
00252   void emptyNodeData(NodeTy init = NodeTy()) {
00253     NodeData = new cache_line_storage<gNode>[numNodes];
00254     for (uint64_t i = 0; i < numNodes; ++i)
00255       NodeData[i].data.data = init;
00256   }
00257 
00258   void prefetch_neighbors(GraphNode N) {
00259     for (neighbor_iterator ii = neighbor_begin(N, NONE),
00260         ee = neighbor_begin(N,NONE); ii != ee; ++ii)
00261       __builtin_prefetch(&NodeData[*ii].data.data);
00262   }
00263 };
00264 
00265 template<>
00266 class LC_FileGraph<void, void>: public FileGraph { 
00267 };
00268 
00269 }
00270 }
00271 #endif