 
     SizeT nodes; // node number of the graph
     SizeT edges; // edge number of the graph
-    SizeT out_nodes; // number of nodes which have outgoing edges
-    SizeT in_nodes; // number of nodes which have incoming edges
+    SizeT out_nodes; // number of nodes that have outgoing edges
+    SizeT in_nodes; // number of nodes that have incoming edges
     DataSlice *d_data_slices;
 
-    //Constructor, Destructor ignored here
+    // The constructor and destructor are ignored here.
 
-    // Extract final hub rank scores and authority rank scores back to CPU
+    // "Extract" copies final hub rank scores and authority rank
+    // scores back to the CPU.
+
     cudaError_t Extract(VertexId *h_hrank, VertexId *h_arank)
     {
         cudaError_t retval = cudaSuccess;

        if (retval = util::GRError(GPUMalloc(data_slices[0]->d_out_degrees, nodes))) break;
        if (retval = util::GRError(GPUMalloc(data_slices[0]->d_hub_predecessors, edges))) break;
        if (retval = util::GRError(GPUMalloc(data_slices[0]->d_auth_predecessors, edges))) break;
        return retval;  
    }

    // Reset function will be loaded before each run of SALSA to reset problem related data.
    cudaError_t Reset(const Csr<VertexId, Value, SizeT> &graph)
    {
        cudaError_t retval = cudaSuccess;
        if (retval = util::GRError(ProblemBase::Reset(graph))) break;

        // Initialize hub and authority rank scores
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_hrank_curr, (Value)1.0/out_nodes, nodes);
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_arank_curr, (Value)1.0/in_nodes, nodes);
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_hrank_next, 0, nodes);
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_arank_next, 0, nodes);

        // Compute in and out degrees for each node
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_out_degrees, 0, nodes);
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_in_degrees, 0, nodes);
        util::MemsetMadVectorKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_out_degrees, BaseProblem::graph_slices[gpu]->d_row_offsets, &BaseProblem::graph_slices[gpu]->d_row_offsets[1], -1, nodes);
        util::MemsetMadVectorKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_in_degrees, BaseProblem::graph_slices[gpu]->d_column_offsets, &BaseProblem::graph_slices[gpu]->d_column_offsets[1], -1, nodes);

        // Initialize predecessors to INVALID_PREDECESSOR_ID
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_hub_predecessors, INVALID_PREDECESSOR_ID, edges);
        util::MemsetKernel<<<BLOCK, THREAD>>>(data_slices[0]->d_auth_predecessors, INVALID_PREDECESSOR_ID, edges);

        return retval;  
    }
};

// This data structure (the "Problem" struct) stores the graph
// topology in CSR format and the frontier. All Problem structs
// inherit from the ProblemBase struct. Algorithm-specific data is
// stored in a "DataSlice".

template<
typename VertexId,
