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 bool operator()(const GNode& a, const GNode& b) {
00041 return a.getData() < b.getData();
00042 }
00043 };
00044
00051 template<typename Graph>
00052 bool outputGraph(const char* file, Graph& G) {
00053 ssize_t retval;
00054
00055 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
00056 int fd = open(file, O_WRONLY | O_CREAT |O_TRUNC, mode);
00057
00058
00059 uint64_t version = 1;
00060 retval = write(fd, &version, sizeof(uint64_t));
00061 if (retval == -1) {
00062 perror(__FILE__);
00063 abort();
00064 }
00065
00066 uint64_t sizeof_edge_data = sizeof(typename Graph::EdgeDataTy);
00067 retval = write(fd, &sizeof_edge_data, sizeof(uint64_t));
00068 if (retval == -1) {
00069 perror(__FILE__);
00070 abort();
00071 }
00072
00073
00074 uint64_t num_nodes = G.size();
00075 retval = write(fd, &num_nodes, sizeof(uint64_t));
00076 if (retval == -1) {
00077 perror(__FILE__);
00078 abort();
00079 }
00080
00081 typedef typename Graph::GraphNode GNode;
00082 typedef std::vector<GNode> Nodes;
00083 Nodes nodes;
00084 for (typename Graph::active_iterator ii = G.active_begin(),
00085 ee = G.active_end(); ii != ee; ++ii) {
00086 nodes.push_back(*ii);
00087 }
00088
00089
00090
00091 std::sort(nodes.begin(), nodes.end(), CompareNodeData<Graph>());
00092
00093
00094 uint64_t offset = 0;
00095 std::vector<uint64_t> out_idx;
00096 std::map<typename Graph::GraphNode, uint32_t> node_ids;
00097 for (uint32_t id = 0; id < num_nodes; ++id) {
00098 GNode& node = nodes[id];
00099 node_ids[node] = id;
00100 offset += G.neighborsSize(node);
00101 out_idx.push_back(offset);
00102 }
00103 retval = write(fd, &offset, sizeof(uint64_t));
00104 if (retval == -1) {
00105 perror(__FILE__);
00106 abort();
00107 }
00108
00109
00110 retval = write(fd, &out_idx[0], sizeof(uint64_t) * out_idx.size());
00111 if (retval == -1) {
00112 perror(__FILE__);
00113 abort();
00114 }
00115
00116
00117 size_t num_edges = 0;
00118 for (typename Nodes::iterator ii = nodes.begin(), ee = nodes.end();
00119 ii != ee; ++ii) {
00120 for (typename Graph::neighbor_iterator ni = G.neighbor_begin(*ii),
00121 ne = G.neighbor_end(*ii); ni != ne; ++ni, ++num_edges) {
00122 uint32_t id = node_ids[*ni];
00123 retval = write(fd, &id, sizeof(uint32_t));
00124 if (retval == -1) {
00125 perror(__FILE__);
00126 abort();
00127 }
00128 }
00129 }
00130 if (num_edges % 2) {
00131 uint32_t padding = 0;
00132 retval = write(fd, &padding, sizeof(uint32_t));
00133 if (retval == -1) {
00134 perror(__FILE__);
00135 abort();
00136 }
00137 }
00138
00139
00140 for (typename Nodes::iterator ii = nodes.begin(), ee = nodes.end();
00141 ii != ee; ++ii) {
00142 for (typename Graph::neighbor_iterator ni = G.neighbor_begin(*ii),
00143 ne = G.neighbor_end(*ii); ni != ne; ++ni) {
00144 retval = write(fd, &G.getEdgeData(*ii, *ni),
00145 sizeof(typename Graph::EdgeDataTy));
00146 if (retval == -1) {
00147 perror(__FILE__);
00148 abort();
00149 }
00150 }
00151 }
00152
00153 close(fd);
00154
00155 return true;
00156 }
00157
00159 template<typename Graph>
00160 bool outputTextEdgeData(const char* ofile, Graph& G) {
00161 std::ofstream file(ofile);
00162 for (typename Graph::active_iterator ii = G.active_begin(),
00163 ee = G.active_end(); ii != ee; ++ii) {
00164 for (typename Graph::neighbor_iterator ni = G.neighbor_begin(*ii),
00165 ne = G.neighbor_end(*ii); ni != ne; ++ni) {
00166 file << G.getEdgeData(*ii, *ni) << '\n';
00167 }
00168 }
00169 return true;
00170 }
00171
00172
00173 }
00174 }
00175 #endif