void initializeRawGraph(const std::string& inputFile, RawGraph& raw) {
  typedef Galois::Graph::LC_CSR_Graph<uint32_t, int> ReaderGraph;
  typedef ReaderGraph::GraphNode ReaderGNode;

  ReaderGraph reader;
  reader.structureFromFile(inputFile);

  typedef RawGraph::GraphNode RawGNode;
  typedef std::vector<RawGNode> NodesTy;

  NodesTy rawNodes(reader.size());

  // Assign ids to ReaderGNodes and
  // create dense map between ids and GNodes
  uint32_t id = 0;
  for (ReaderGraph::iterator ii = reader.begin(),
      ee = reader.end(); ii != ee; ++ii, ++id) {
    reader.getData(*ii) = id;
    RawGNode node = raw.createNode(id);
    rawNodes[id] = node;
    raw.addNode(node);
  }

  // Create edges
  for (ReaderGraph::iterator ii = reader.begin(),
      ei = reader.end(); ii != ei; ++ii) {
    ReaderGNode rsrc = *ii;
    uint32_t rsrcId = reader.getData(rsrc);
    for (ReaderGraph::edge_iterator jj = reader.edge_begin(rsrc),
        ej = reader.edge_end(rsrc); jj != ej; ++jj) {
      ReaderGNode rdst = reader.getEdgeDst(jj);
      uint32_t rdstId = reader.getData(rdst);
      int cap = reader.getEdgeData(jj);
      raw.getEdgeData(raw.addEdge(rawNodes[rsrcId], rawNodes[rdstId])) = cap;
      // Add reverse edge if not already there
      if (!reader.hasNeighbor(rdst, rsrc)) {
        raw.getEdgeData(raw.addEdge(rawNodes[rdstId], rawNodes[rsrcId])) = 0;
      }
    }
  }
}
void writePfpGraph(const std::string& inputFile, const std::string& outputFile) {
  typedef Galois::Graph::FileGraph ReaderGraph;
  typedef ReaderGraph::GraphNode ReaderGNode;

  ReaderGraph reader;
  reader.structureFromFile(inputFile);

  typedef Galois::Graph::FileGraphWriter Writer;
  typedef Galois::LargeArray<EdgeTy> EdgeData;
  typedef typename EdgeData::value_type edge_value_type;

  Writer p;
  EdgeData edgeData;

  // Count edges
  size_t numEdges = 0;
  for (ReaderGraph::iterator ii = reader.begin(), ei = reader.end(); ii != ei; ++ii) {
    ReaderGNode rsrc = *ii;
    for (ReaderGraph::edge_iterator jj = reader.edge_begin(rsrc),
        ej = reader.edge_end(rsrc); jj != ej; ++jj) {
      ReaderGNode rdst = reader.getEdgeDst(jj);
      if (rsrc == rdst) continue;
      if (!reader.hasNeighbor(rdst, rsrc)) 
        ++numEdges;
      ++numEdges;
    }
  }

  p.setNumNodes(reader.size());
  p.setNumEdges(numEdges);
  p.setSizeofEdgeData(sizeof(edge_value_type));

  p.phase1();
  for (ReaderGraph::iterator ii = reader.begin(), ei = reader.end(); ii != ei; ++ii) {
    ReaderGNode rsrc = *ii;
    for (ReaderGraph::edge_iterator jj = reader.edge_begin(rsrc),
        ej = reader.edge_end(rsrc); jj != ej; ++jj) {
      ReaderGNode rdst = reader.getEdgeDst(jj);
      if (rsrc == rdst) continue;
      if (!reader.hasNeighbor(rdst, rsrc)) 
        p.incrementDegree(rdst);
      p.incrementDegree(rsrc);
    }
  }

  EdgeTy one = 1;
  static_assert(sizeof(one) == sizeof(uint32_t), "Unexpected edge data size");
  one = Galois::convert_le32(one);

  p.phase2();
  edgeData.create(numEdges);
  for (ReaderGraph::iterator ii = reader.begin(), ei = reader.end(); ii != ei; ++ii) {
    ReaderGNode rsrc = *ii;
    for (ReaderGraph::edge_iterator jj = reader.edge_begin(rsrc),
        ej = reader.edge_end(rsrc); jj != ej; ++jj) {
      ReaderGNode rdst = reader.getEdgeDst(jj);
      if (rsrc == rdst) continue;
      if (!reader.hasNeighbor(rdst, rsrc)) 
        edgeData.set(p.addNeighbor(rdst, rsrc), 0);
      EdgeTy cap = useUnitCapacity ? one : reader.getEdgeData<EdgeTy>(jj);
      edgeData.set(p.addNeighbor(rsrc, rdst), cap);
    }
  }

  edge_value_type* rawEdgeData = p.finish<edge_value_type>();
  std::copy(edgeData.begin(), edgeData.end(), rawEdgeData);

  p.structureToFile(outputFile);
}