 #include "util.h"
 #include "graphio.h"
 #include "refgas.h"
+#include "gpugas.h"
+#include <climits>
 
 struct SSSP
 {



  typedef int GatherResult;
  static int gatherZero; //this should be set to nVertices + 1


  static int gatherReduce(const int& left, const int& right)
  {
    return min(left, right);
  }


  static int gatherMap(const VertexData* dst, const VertexData *src, const EdgeData* edge)
  {
    return src->dist + edge->length;
  }


  static bool apply(VertexData* vert, int dist)
  {
    bool changed = dist < vert->dist;


  //initialize vertex data
  std::vector<SSSP::VertexData> vertexData(nVertices);

  {
    for( int i = 0; i < nVertices; ++i ) {
      if (i != sourceVertex)
        vertexData[i].dist = nVertices + 1; //larger than max diameter
      else
        vertexData[i].dist = 0;
    }

    GASEngineRef<SSSP> engine;
    engine.setGraph(nVertices, &vertexData[0], srcs.size(), (SSSP::EdgeData *)&edge_data[0], &srcs[0], &dsts[0]);

    //TODO, setting all vertices to active for first step works, but it would
    //be faster to instead set to neighbors of starting vertex
    engine.setActive(0, nVertices);
    engine.run();
    engine.getResults();

    //output distances;
    for (int i = 0; i < nVertices; ++i)
      printf("%d %d\n", i, vertexData[i].dist);
  }

   {
    for( int i = 0; i < nVertices; ++i ) {
      if (i != sourceVertex)
        vertexData[i].dist = nVertices + 1; //larger than max diameter
      else
        vertexData[i].dist = 0;
    }

    GASEngineGPU<SSSP> engine;
    engine.setGraph(nVertices, &vertexData[0], srcs.size(), (SSSP::EdgeData *)&edge_data[0], &srcs[0], &dsts[0]);

    //TODO, setting all vertices to active for first step works, but it would
    //be faster to instead set to neighbors of starting vertex
    engine.setActive(0, nVertices);
    engine.run();
    engine.getResults();

    //output distances;
    for (int i = 0; i < nVertices; ++i)
      printf("%d %d\n", i, vertexData[i].dist);
   }
}
