<commit_before>// ----------------------------------------------------------------
// Gunrock -- Fast and Efficient GPU Graph Library
// ----------------------------------------------------------------
// This source code is distributed under the terms of LICENSE.TXT
// in the root directory of this source distribution.
// ----------------------------------------------------------------

/**
 * @file
 * csr.cuh
 *
 * @brief CSR (Column Sparse Row) Graph Data Structure
 */

#pragma once

#include <time.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <iterator>

#include <gunrock/util/error_utils.cuh>

using namespace std;

namespace gunrock {

/**
 * @brief CSR data structure which uses Compressed Sparse Row
 * format to store a graph. It is a compressed way to present
 * the graph as a sparse matrix.
 */
template<typename VertexId, typename Value, typename SizeT>
struct Csr
{
    SizeT nodes;    /**< Number of nodes in the graph. */
    SizeT edges;    /**< Number of edges in the graph. */
    SizeT out_nodes; /**< Number of nodes which have outgoing edges. */
    SizeT average_degree;

    VertexId    *column_indices;/**< Column indices corresponding to all the non-zero values in the sparse matrix. */
    SizeT       *row_offsets;   /**< List of indices where each row of the sparse matrix starts. */
    Value       *edge_values;   /**< List of values attached to edges in the graph. */
    Value       *node_values;   /**< List of values attached to nodes in the graph. */

    Value       average_edge_value;
    Value       average_node_value;

    bool        pinned;        /**< Whether to use pinned memory */

    /**
     * @brief CSR Constructor
     *
     * @param[in] pinned Use pinned memory for CSR data structure
     * (default: do not use pinned memory)
     */
    Csr(bool pinned = false)
    {
        nodes = 0;
        edges = 0;
        average_degree = 0;
        average_edge_value = 0;
        average_node_value = 0;
        out_nodes = -1;
        row_offsets = NULL;
        column_indices = NULL;
        edge_values = NULL;
        node_values = NULL;
        this->pinned = pinned;
    }

    /**
     * @brief Allocate memory for CSR graph.
     *
     * @param[in] nodes Number of nodes in COO-format graph
     * @param[in] edges Number of edges in COO-format graph
     */
    template <bool LOAD_EDGE_VALUES, bool LOAD_NODE_VALUES>
    void FromScratch(SizeT nodes, SizeT edges)
    {
        this->nodes = nodes;
        this->edges = edges;

        if (pinned) {

            // Put our graph in pinned memory
            int flags = cudaHostAllocMapped;
            if (gunrock::util::GRError(
                    cudaHostAlloc((void **)&row_offsets,
                                  sizeof(SizeT) * (nodes + 1), flags),
                    "Csr cudaHostAlloc row_offsets failed", __FILE__, __LINE__))
                exit(1);
            if (gunrock::util::GRError(
                    cudaHostAlloc((void **)&column_indices,
                                  sizeof(VertexId) * edges, flags),
                    "Csr cudaHostAlloc column_indices failed",
                    __FILE__, __LINE__))
                exit(1);

            if (LOAD_NODE_VALUES) {
                if (gunrock::util::GRError(
                        cudaHostAlloc((void **)&node_values,
                                      sizeof(Value) * nodes, flags),
                        "Csr cudaHostAlloc node_values failed",
                        __FILE__, __LINE__))
                    exit(1);
            }

            if (LOAD_EDGE_VALUES) {
                if (gunrock::util::GRError(
                        cudaHostAlloc((void **)&edge_values,
                                      sizeof(Value) * edges, flags),
                        "Csr cudaHostAlloc edge_values failed",
                        __FILE__, __LINE__))
                    exit(1);
            }

        } else {

            // Put our graph in regular memory
            row_offsets = (SizeT*) malloc(sizeof(SizeT) * (nodes + 1));
            column_indices = (VertexId*) malloc(sizeof(VertexId) * edges);
            node_values = (LOAD_NODE_VALUES) ?
                (Value*) malloc(sizeof(Value) * nodes) : NULL;
            edge_values = (LOAD_EDGE_VALUES) ?
                (Value*) malloc(sizeof(Value) * edges) : NULL;
        }
    }

    /**
     * @store graph information into files
     * 
     */
  void WriteToFile(char * file_name,
		   bool undirected, 
		   bool reversed,
		   SizeT num_nodes, 
		   SizeT num_edges, 
		   Value *row_offsets,
		   Value *col_indices,
		   Value *edge_values = NULL)
  {
    printf("==> Writing into file:  %s\n", file_name);
    
    time_t mark1 = time(NULL);
    
    std::ofstream output(file_name);
    
    if (output.is_open())
    {
      output << num_nodes << " " << num_edges << " ";
      std::copy(row_offsets, row_offsets + num_nodes, ostream_iterator<int>(output, " "));
      std::copy(column_indices, column_indices + num_edges, ostream_iterator<int>(output, " "));
      if (edge_values != NULL)
      {
	std::copy(edge_values, edge_values + num_edges, ostream_iterator<int>(output, " "));
      }
      output.close();
    }
    else
    {
      std::cout << "Cannot Open The File." << std::endl;
    }

    time_t mark2 = time(NULL);
    printf("Finished writing in %ds.\n", (int)(mark2 - mark1));
  }

  // read from stored row_offsets, column_indices arrays
  template <bool LOAD_EDGE_VALUES>
  void FromCsr(char *f_in, 
	       bool undirected, 
	       bool reversed)
  {
    printf("  Reading directly from previously stored CSR arrays ...\n");
    
    ifstream _file(f_in);
    
    if (_file.is_open())
    {
      time_t mark1 = time(NULL);
      
      std::istream_iterator<int> start(_file), end;
      std::vector<int> v(start, end);
      
      SizeT csr_nodes = v.at(0);
      SizeT csr_edges = v.at(1);
      
      FromScratch<LOAD_EDGE_VALUES, false>(csr_nodes, csr_edges); 
      
      copy(v.begin()+2, v.begin()+2+csr_nodes, row_offsets);
      copy(v.begin()+2+csr_nodes, v.begin()+2+csr_nodes+csr_edges, column_indices);
      if(LOAD_EDGE_VALUES) 
      { 
	copy(v.begin()+2+csr_nodes+csr_edges, v.end(), edge_values); 
      }
      
      time_t mark2 = time(NULL);
      printf("Done reading (%ds).\n", (int) (mark2 - mark1));
      
      v.clear();
    }
    else 
    {<commit_msg>fix a bug<commit_after>// ----------------------------------------------------------------
// Gunrock -- Fast and Efficient GPU Graph Library
// ----------------------------------------------------------------
// This source code is distributed under the terms of LICENSE.TXT
// in the root directory of this source distribution.
// ----------------------------------------------------------------

/**
 * @file
 * csr.cuh
 *
 * @brief CSR (Column Sparse Row) Graph Data Structure
 */

#pragma once

#include <time.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <iterator>

#include <gunrock/util/error_utils.cuh>

using namespace std;

namespace gunrock {

/**
 * @brief CSR data structure which uses Compressed Sparse Row
 * format to store a graph. It is a compressed way to present
 * the graph as a sparse matrix.
 */
template<typename VertexId, typename Value, typename SizeT>
struct Csr
{
    SizeT nodes;    /**< Number of nodes in the graph. */
    SizeT edges;    /**< Number of edges in the graph. */
    SizeT out_nodes; /**< Number of nodes which have outgoing edges. */
    SizeT average_degree;

    VertexId    *column_indices;/**< Column indices corresponding to all the non-zero values in the sparse matrix. */
    SizeT       *row_offsets;   /**< List of indices where each row of the sparse matrix starts. */
    Value       *edge_values;   /**< List of values attached to edges in the graph. */
    Value       *node_values;   /**< List of values attached to nodes in the graph. */

    Value       average_edge_value;
    Value       average_node_value;

    bool        pinned;        /**< Whether to use pinned memory */

    /**
     * @brief CSR Constructor
     *
     * @param[in] pinned Use pinned memory for CSR data structure
     * (default: do not use pinned memory)
     */
    Csr(bool pinned = false)
    {
        nodes = 0;
        edges = 0;
        average_degree = 0;
        average_edge_value = 0;
        average_node_value = 0;
        out_nodes = -1;
        row_offsets = NULL;
        column_indices = NULL;
        edge_values = NULL;
        node_values = NULL;
        this->pinned = pinned;
    }

    /**
     * @brief Allocate memory for CSR graph.
     *
     * @param[in] nodes Number of nodes in COO-format graph
     * @param[in] edges Number of edges in COO-format graph
     */
    template <bool LOAD_EDGE_VALUES, bool LOAD_NODE_VALUES>
    void FromScratch(SizeT nodes, SizeT edges)
    {
        this->nodes = nodes;
        this->edges = edges;

        if (pinned) {

            // Put our graph in pinned memory
            int flags = cudaHostAllocMapped;
            if (gunrock::util::GRError(
                    cudaHostAlloc((void **)&row_offsets,
                                  sizeof(SizeT) * (nodes + 1), flags),
                    "Csr cudaHostAlloc row_offsets failed", __FILE__, __LINE__))
                exit(1);
            if (gunrock::util::GRError(
                    cudaHostAlloc((void **)&column_indices,
                                  sizeof(VertexId) * edges, flags),
                    "Csr cudaHostAlloc column_indices failed",
                    __FILE__, __LINE__))
                exit(1);

            if (LOAD_NODE_VALUES) {
                if (gunrock::util::GRError(
                        cudaHostAlloc((void **)&node_values,
                                      sizeof(Value) * nodes, flags),
                        "Csr cudaHostAlloc node_values failed",
                        __FILE__, __LINE__))
                    exit(1);
            }

            if (LOAD_EDGE_VALUES) {
                if (gunrock::util::GRError(
                        cudaHostAlloc((void **)&edge_values,
                                      sizeof(Value) * edges, flags),
                        "Csr cudaHostAlloc edge_values failed",
                        __FILE__, __LINE__))
                    exit(1);
            }

        } else {

            // Put our graph in regular memory
            row_offsets = (SizeT*) malloc(sizeof(SizeT) * (nodes + 1));
            column_indices = (VertexId*) malloc(sizeof(VertexId) * edges);
            node_values = (LOAD_NODE_VALUES) ?
                (Value*) malloc(sizeof(Value) * nodes) : NULL;
            edge_values = (LOAD_EDGE_VALUES) ?
                (Value*) malloc(sizeof(Value) * edges) : NULL;
        }
    }

    /**
     * @store graph information into files
     * 
     */
  void WriteToFile(char * file_name,
		   bool undirected, 
		   bool reversed,
		   SizeT num_nodes, 
		   SizeT num_edges, 
		   Value *row_offsets,
		   Value *col_indices,
		   Value *edge_values = NULL)
  {
    printf("==> Writing into file:  %s\n", file_name);
    
    time_t mark1 = time(NULL);
    
    std::ofstream output(file_name);
    
    if (output.is_open())
    {
      output << num_nodes << " " << num_edges << " ";
      std::copy(row_offsets,   row_offsets + num_nodes + 1, ostream_iterator<int>(output, " "));
      std::copy(column_indices, column_indices + num_edges, ostream_iterator<int>(output, " "));
      if (edge_values != NULL)
      {
	std::copy(edge_values, edge_values + num_edges, ostream_iterator<int>(output, " "));
      }
      output.close();
    }
    else
    {
      std::cout << "Cannot Open The File." << std::endl;
    }

    time_t mark2 = time(NULL);
    printf("Finished writing in %ds.\n", (int)(mark2 - mark1));
  }

  // read from stored row_offsets, column_indices arrays
  template <bool LOAD_EDGE_VALUES>
  void FromCsr(char *f_in, 
	       bool undirected, 
	       bool reversed)
  {
    printf("  Reading directly from previously stored CSR arrays ...\n");
    
    ifstream _file(f_in);
    
    if (_file.is_open())
    {
      time_t mark1 = time(NULL);
      
      std::istream_iterator<int> start(_file), end;
      std::vector<int> v(start, end);
      
      SizeT csr_nodes = v.at(0);
      SizeT csr_edges = v.at(1);
      
      FromScratch<LOAD_EDGE_VALUES, false>(csr_nodes, csr_edges); 
      
      copy(v.begin()+2, v.begin()+3+csr_nodes, row_offsets);
      copy(v.begin()+3+csr_nodes, v.begin()+3+csr_nodes+csr_edges, column_indices);
      if(LOAD_EDGE_VALUES) 
      { 
	copy(v.begin()+3+csr_nodes+csr_edges, v.end(), edge_values); 
      }
      
      time_t mark2 = time(NULL);
      printf("Done reading (%ds).\n", (int) (mark2 - mark1));
      
      v.clear();
    }
    else 
    {
{'fraction_non_alphanumeric': 0.13978411719352352, 'fraction_numerical': 0.004240555127216654, 'mean_word_length': 1.7804930332261522, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3166958', 'n_tokens_mistral': 4001, 'n_tokens_neox': 3793, 'n_words': 1007}