00001
00023 #ifndef GALOIS_GRAPHS_SERIALIZE_H
00024 #define GALOIS_GRAPHS_SERIALIZE_H
00025
00026 #include <sys/stat.h>
00027 #include <stdio.h>
00028 #include <fcntl.h>
00029 #include <unistd.h>
00030
00031 #include <fstream>
00032 #include <algorithm>
00033
00034 namespace Galois {
00035 namespace Graph {
00036
00037 template<typename Graph>
00038 struct CompareNodeData {
00039 typedef typename Graph::GraphNode GNode;
00040 Graph& g;
00041 CompareNodeData(Graph& _g): g(_g) { }
00042 bool operator()(const GNode& a, const GNode& b) {
00043 return g.getData(a) < g.getData(b);
00044 }
00045 };
00046
00053 template<typename Graph>
00054 bool outputGraph(const char* file, Graph& G) {
00055 ssize_t retval;
00056
00057 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
00058 int fd = open(file, O_WRONLY | O_CREAT |O_TRUNC, mode);
00059 if (fd == -1) {
00060 GALOIS_SYS_ERROR(true, "failed opening %s", file);
00061 }
00062
00063
00064 uint64_t version = 1;
00065 retval = write(fd, &version, sizeof(uint64_t));
00066 if (retval == -1 || retval != sizeof(uint64_t)) {
00067 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00068 }
00069
00070 uint64_t sizeof_edge_data = G.sizeOfEdgeData();
00071 retval = write(fd, &sizeof_edge_data, sizeof(uint64_t));
00072 if (retval == -1 || retval != sizeof(uint64_t)) {
00073 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00074 }
00075
00076
00077 uint64_t num_nodes = G.size();
00078 retval = write(fd, &num_nodes, sizeof(uint64_t));
00079 if (retval == -1 || retval != sizeof(uint64_t)) {
00080 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00081 }
00082
00083 typedef typename Graph::GraphNode GNode;
00084 typedef std::vector<GNode> Nodes;
00085 Nodes nodes;
00086 for (typename Graph::iterator ii = G.begin(),
00087 ee = G.end(); ii != ee; ++ii) {
00088 nodes.push_back(*ii);
00089 }
00090
00091
00092
00093 std::sort(nodes.begin(), nodes.end(), CompareNodeData<Graph>(G));
00094
00095
00096 uint64_t offset = 0;
00097 std::vector<uint64_t> out_idx;
00098 std::map<typename Graph::GraphNode, uint32_t> node_ids;
00099 for (uint32_t id = 0; id < num_nodes; ++id) {
00100 GNode& node = nodes[id];
00101 node_ids[node] = id;
00102 offset += std::distance(G.edge_begin(node), G.edge_end(node));
00103 out_idx.push_back(offset);
00104 }
00105 retval = write(fd, &offset, sizeof(uint64_t));
00106 if (retval == -1 || retval != sizeof(uint64_t)) {
00107 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00108 }
00109
00110
00111 char* ptr = (char*) &out_idx[0];
00112 size_t total = sizeof(uint64_t) * out_idx.size();
00113 ssize_t written;
00114 while (total) {
00115 written = write(fd, ptr, total);
00116 if (written == -1) {
00117 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00118 } else if (written == 0) {
00119 GALOIS_ERROR(true, "ran out of space writing to %s", file);
00120 }
00121 total -= written;
00122 ptr += written;
00123 }
00124
00125
00126 size_t num_edges = 0;
00127 for (typename Nodes::iterator ii = nodes.begin(), ee = nodes.end();
00128 ii != ee; ++ii) {
00129 for (typename Graph::edge_iterator jj = G.edge_begin(*ii),
00130 ej = G.edge_end(*ii); jj != ej; ++jj, ++num_edges) {
00131 uint32_t id = node_ids[G.getEdgeDst(jj)];
00132 retval = write(fd, &id, sizeof(uint32_t));
00133 if (retval == -1 || retval != sizeof(uint32_t)) {
00134 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00135 }
00136 }
00137 }
00138 if (num_edges % 2) {
00139 uint32_t padding = 0;
00140 retval = write(fd, &padding, sizeof(uint32_t));
00141 if (retval == -1 || retval != sizeof(uint32_t)) {
00142 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00143 }
00144 }
00145
00146
00147 if (sizeof_edge_data) {
00148 for (typename Nodes::iterator ii = nodes.begin(), ee = nodes.end();
00149 ii != ee; ++ii) {
00150 for (typename Graph::edge_iterator jj = G.edge_begin(*ii),
00151 ej = G.edge_end(*ii); jj != ej; ++jj) {
00152 void *b = &G.getEdgeData(jj);
00153 retval = write(fd, b, sizeof_edge_data);
00154 if (retval == -1 || retval != (int) sizeof_edge_data) {
00155 GALOIS_SYS_ERROR(true, "failed writing to %s", file);
00156 }
00157 }
00158 }
00159 }
00160
00161 close(fd);
00162
00163 return true;
00164 }
00165
00167 template<typename Graph>
00168 bool outputTextEdgeData(const char* ofile, Graph& G) {
00169 std::ofstream file(ofile);
00170 for (typename Graph::iterator ii = G.begin(),
00171 ee = G.end(); ii != ee; ++ii) {
00172 for (typename Graph::edge_iterator jj = G.edge_iterator(*ii),
00173 ej = G.edge_iterator(*ii); jj != ej; ++jj) {
00174 file << G.getEdgeData(jj) << '\n';
00175 }
00176 }
00177 return true;
00178 }
00179
00180
00181 }
00182 }
00183 #endif