26 #ifndef GALOIS_GRAPHS_BUFGRAPH_H
27 #define GALOIS_GRAPHS_BUFGRAPH_H
31 #include <boost/iterator/counting_iterator.hpp>
33 #include "galois/config.h"
48 template <
typename EdgeDataType>
53 uint64_t* outIndexBuffer =
nullptr;
55 uint32_t* edgeDestBuffer =
nullptr;
57 EdgeDataType* edgeDataBuffer =
nullptr;
60 uint32_t globalSize = 0;
62 uint64_t globalEdgeSize = 0;
65 uint32_t numLocalNodes = 0;
67 uint64_t numLocalEdges = 0;
71 uint64_t nodeOffset = 0;
74 uint64_t edgeOffset = 0;
76 bool graphLoaded =
false;
94 void loadOutIndex(std::ifstream& graphFile, uint64_t nodeStart,
95 uint64_t numNodesToLoad) {
96 if (numNodesToLoad == 0) {
99 assert(outIndexBuffer ==
nullptr);
100 outIndexBuffer = (uint64_t*)malloc(
sizeof(uint64_t) * numNodesToLoad);
102 if (outIndexBuffer ==
nullptr) {
103 GALOIS_DIE(
"Failed to allocate memory for out index buffer.");
107 uint64_t readPosition = (4 + nodeStart) *
sizeof(uint64_t);
108 graphFile.seekg(readPosition);
110 uint64_t numBytesToLoad = numNodesToLoad *
sizeof(uint64_t);
111 uint64_t bytesRead = 0;
113 while (numBytesToLoad > 0) {
114 graphFile.read(((
char*)this->outIndexBuffer) + bytesRead, numBytesToLoad);
115 size_t numRead = graphFile.gcount();
116 numBytesToLoad -= numRead;
117 bytesRead += numRead;
120 assert(numBytesToLoad == 0);
122 nodeOffset = nodeStart;
134 void loadEdgeDest(std::ifstream& graphFile, uint64_t edgeStart,
135 uint64_t numEdgesToLoad, uint64_t numGlobalNodes) {
136 if (numEdgesToLoad == 0) {
140 assert(edgeDestBuffer ==
nullptr);
141 edgeDestBuffer = (uint32_t*)malloc(
sizeof(uint32_t) * numEdgesToLoad);
143 if (edgeDestBuffer ==
nullptr) {
144 GALOIS_DIE(
"Failed to allocate memory for edge dest buffer.");
148 uint64_t readPosition = (4 + numGlobalNodes) *
sizeof(uint64_t) +
149 (
sizeof(uint32_t) * edgeStart);
150 graphFile.seekg(readPosition);
152 uint64_t numBytesToLoad = numEdgesToLoad *
sizeof(uint32_t);
153 uint64_t bytesRead = 0;
154 while (numBytesToLoad > 0) {
155 graphFile.read(((
char*)this->edgeDestBuffer) + bytesRead, numBytesToLoad);
156 size_t numRead = graphFile.gcount();
157 numBytesToLoad -= numRead;
158 bytesRead += numRead;
161 assert(numBytesToLoad == 0);
163 edgeOffset = edgeStart;
180 typename std::enable_if<!std::is_void<EdgeType>::value>::type* =
nullptr>
181 void loadEdgeData(std::ifstream& graphFile, uint64_t edgeStart,
182 uint64_t numEdgesToLoad, uint64_t numGlobalNodes,
183 uint64_t numGlobalEdges) {
186 if (numEdgesToLoad == 0) {
190 assert(edgeDataBuffer ==
nullptr);
192 (EdgeDataType*)malloc(
sizeof(EdgeDataType) * numEdgesToLoad);
194 if (edgeDataBuffer ==
nullptr) {
195 GALOIS_DIE(
"Failed to allocate memory for edge data buffer.");
199 uint64_t baseReadPosition = (4 + numGlobalNodes) *
sizeof(uint64_t) +
200 (
sizeof(uint32_t) * numGlobalEdges);
203 if (numGlobalEdges % 2) {
204 baseReadPosition +=
sizeof(uint32_t);
208 uint64_t readPosition =
209 baseReadPosition + (
sizeof(EdgeDataType) * edgeStart);
210 graphFile.seekg(readPosition);
211 uint64_t numBytesToLoad = numEdgesToLoad *
sizeof(EdgeDataType);
212 uint64_t bytesRead = 0;
214 while (numBytesToLoad > 0) {
215 graphFile.read(((
char*)this->edgeDataBuffer) + bytesRead, numBytesToLoad);
216 size_t numRead = graphFile.gcount();
217 numBytesToLoad -= numRead;
218 bytesRead += numRead;
221 assert(numBytesToLoad == 0);
234 typename std::enable_if<std::is_void<EdgeType>::value>::type* =
nullptr>
235 void loadEdgeData(std::ifstream&, uint64_t, uint64_t, uint64_t, uint64_t) {
243 void resetGraphStatus() {
258 free(outIndexBuffer);
259 outIndexBuffer =
nullptr;
260 free(edgeDestBuffer);
261 edgeDestBuffer =
nullptr;
262 free(edgeDataBuffer);
263 edgeDataBuffer =
nullptr;
294 uint32_t
size()
const {
return globalSize; }
314 GALOIS_DIE(
"Cannot load an buffered graph more than once.");
317 std::ifstream graphFile(filename.c_str());
319 graphFile.read(((
char*)header),
sizeof(uint64_t) * 4);
321 numLocalNodes = globalSize = header[2];
322 numLocalEdges = globalEdgeSize = header[3];
324 loadOutIndex(graphFile, 0, globalSize);
325 loadEdgeDest(graphFile, 0, globalEdgeSize, globalSize);
327 loadEdgeData<EdgeDataType>(graphFile, 0, globalEdgeSize, globalSize,
349 uint64_t nodeEnd, uint64_t edgeStart, uint64_t
edgeEnd,
350 uint64_t numGlobalNodes, uint64_t numGlobalEdges) {
352 GALOIS_DIE(
"Cannot load an buffered graph more than once.");
355 std::ifstream graphFile(filename.c_str());
357 globalSize = numGlobalNodes;
358 globalEdgeSize = numGlobalEdges;
360 assert(nodeEnd >= nodeStart);
361 numLocalNodes = nodeEnd - nodeStart;
362 loadOutIndex(graphFile, nodeStart, numLocalNodes);
364 assert(edgeEnd >= edgeStart);
365 numLocalEdges = edgeEnd - edgeStart;
366 loadEdgeDest(graphFile, edgeStart, numLocalEdges, numGlobalNodes);
369 loadEdgeData<EdgeDataType>(graphFile, edgeStart, numLocalEdges,
370 numGlobalNodes, numGlobalEdges);
391 if (numLocalNodes == 0) {
394 assert(nodeOffset <= globalNodeID);
395 assert(globalNodeID < (nodeOffset + numLocalNodes));
397 uint64_t localNodeID = globalNodeID - nodeOffset;
399 if (localNodeID != 0) {
400 numBytesReadOutIndex +=
sizeof(uint64_t);
419 if (numLocalNodes == 0) {
422 assert(nodeOffset <= globalNodeID);
423 assert(globalNodeID < (nodeOffset + numLocalNodes));
425 numBytesReadOutIndex +=
sizeof(uint64_t);
427 uint64_t localNodeID = globalNodeID - nodeOffset;
442 if (numLocalEdges == 0) {
445 assert(edgeOffset <= globalEdgeID);
446 assert(globalEdgeID < (edgeOffset + numLocalEdges));
448 numBytesReadEdgeDest +=
sizeof(uint32_t);
450 uint64_t localEdgeID = globalEdgeID - edgeOffset;
451 return edgeDestBuffer[localEdgeID];
460 template <
typename K = EdgeDataType,
461 typename std::enable_if<!std::is_void<K>::value>::type* =
nullptr>
466 if (edgeDataBuffer ==
nullptr) {
467 GALOIS_DIE(
"Trying to get edge data when graph has no edge data.");
470 if (numLocalEdges == 0) {
474 assert(edgeOffset <= globalEdgeID);
475 assert(globalEdgeID < (edgeOffset + numLocalEdges));
477 numBytesReadEdgeData +=
sizeof(EdgeDataType);
479 uint64_t localEdgeID = globalEdgeID - edgeOffset;
480 return edgeDataBuffer[localEdgeID];
486 template <
typename K = EdgeDataType,
487 typename std::enable_if<std::is_void<K>::value>::type* =
nullptr>
489 galois::gWarn(
"Getting edge data on graph when it doesn't exist\n");
497 numBytesReadOutIndex.
reset();
498 numBytesReadEdgeDest.
reset();
499 numBytesReadEdgeData.
reset();
509 return numBytesReadOutIndex.
reduce() + numBytesReadEdgeDest.
reduce() +
510 numBytesReadEdgeData.
reduce();
EdgeIterator edgeEnd(uint64_t globalNodeID)
Get the index to the first edge of the node after the provided node.
Definition: BufferedGraph.h:414
void reset()
Definition: Reduction.h:113
Class that loads a portion of a Galois graph from disk directly into memory buffers for access...
Definition: BufferedGraph.h:49
EdgeIterator edgeBegin(uint64_t globalNodeID)
Get the index to the first edge of the provided node THAT THIS GRAPH HAS LOADED (not necessary the fi...
Definition: BufferedGraph.h:386
EdgeDataType edgeData(uint64_t globalEdgeID)
Get the edge data of some edge.
Definition: BufferedGraph.h:462
void gDebug(Args &&...GALOIS_USED_ONLY_IN_DEBUG(args))
Prints a debug string from a sequence of things; prints nothing if NDEBUG is defined.
Definition: gIO.h:72
uint32_t size() const
Gets the number of global nodes in the graph.
Definition: BufferedGraph.h:294
#define GALOIS_DIE(...)
Definition: gIO.h:96
void resetReadCounters()
Reset reading counters.
Definition: BufferedGraph.h:496
void loadPartialGraph(const std::string &filename, uint64_t nodeStart, uint64_t nodeEnd, uint64_t edgeStart, uint64_t edgeEnd, uint64_t numGlobalNodes, uint64_t numGlobalEdges)
Given a node/edge range to load, loads the specified portion of the graph into memory buffers using r...
Definition: BufferedGraph.h:348
~BufferedGraph() noexcept
On destruction, free allocated buffers (if necessary).
Definition: BufferedGraph.h:276
uint32_t sizeEdges() const
Gets the number of global edges in the graph.
Definition: BufferedGraph.h:301
uint64_t getNodeOffset() const
Definition: BufferedGraph.h:304
unsigned edgeData(uint64_t)
Version of above function when edge data type is void.
Definition: BufferedGraph.h:488
BufferedGraph()
Class vars should be initialized by in-class initialization; all left is to reset read counters...
Definition: BufferedGraph.h:271
uint64_t getBytesRead()
Returns the total number of bytes read from this graph so far.
Definition: BufferedGraph.h:508
BufferedGraph & operator=(const BufferedGraph &)=delete
disabled copy constructor operator
T & reduce()
Returns the final reduction value.
Definition: Reduction.h:102
void loadGraph(const std::string &filename)
Loads given Galois CSR graph into memory.
Definition: BufferedGraph.h:312
boost::counting_iterator< uint64_t > EdgeIterator
Edge iterator typedef.
Definition: BufferedGraph.h:377
void gWarn(Args &&...args)
Prints a warning string from a sequence of things.
Definition: gIO.h:63
void resetAndFree()
Free all of the in memory buffers in this object and reset graph status.
Definition: BufferedGraph.h:516
uint64_t edgeDestination(uint64_t globalEdgeID)
Get the global node id of the destination of the provided edge.
Definition: BufferedGraph.h:437