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