<commit_before>#pragma once

#include <functional>
#include <touchstone/benchmark.h>
#include <touchstone/enumeration_range.h>
#include <touchstone/state.h>
#include <boost/container/flat_set.hpp>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include <memory>
#include <algorithm>
#include <numeric>

namespace touchstone {

class BenchmarkSet {
  static const int kNullBenchmarkId = -1;
 public:
  using Runner = std::function<void(BenchmarkSet&)>;

  BenchmarkSet(std::string&& name, Runner&& runner)
    : _name(std::move(name))
    , _runner(std::move(runner))
  {
  }

  int add(const Benchmark& benchmark) {
    int id = _benchmarks.size();
    auto was_inserted = _benchmarks.insert(benchmark);
    if(!was_inserted.second) {
      std::cerr << "bechmark " << benchmark.name() << " is not unique for benchmark "
                << _name << std::endl;
      std::abort();
    }
    was_inserted.first->set_id(id);
    return id;
  }

  void run() {
    assert(_runner && "runner is not set");
    assert(_num_trials > 0 && "num trials is not set");
    assert(_num_epochs > 0 && "num epochs is not set");

    // run through the benchmark set a single time
    // to invoke callbacks that add each individual
    // benchmark
    _runner(*this);

    // repeatedly invoke the runner function until each benchmark 
    // has been run range_size x num_epochs x num_trials times. 
    // The global random number generator should be identically
    // seeded for every (range_value, trial_id) pair.
    std::random_device random_device;
    for(_epoch_id=0; _epoch_id<_num_epochs; ++_epoch_id) {
      _n        = _enumeration_range->begin();
      int last  = _enumeration_range->end();
      for(; _n < last; _n = _enumeration_range->advance(_n)) {
        State::get_n() = _n;
        auto random_seed = random_device();
        for(auto& benchmark : _benchmarks) {
          _current_benchmark = &benchmark;
          for(int trial_id=0; trial_id<_num_trials; ++trial_id) {
            State::get_random_number_generator().seed(random_seed);
            _runner(*this);
          }
        }
      }
    }
    _current_benchmark = nullptr;
  }

  void record_elapse(double elapse) {
    _current_benchmark->add_result(_n, _epoch_id, elapse);
  }

  void set_enumeration_range(std::shared_ptr<const EnumerationRange>&& enumeration_range) {<commit_msg>fix bug with initialization of n<commit_after>#pragma once

#include <functional>
#include <touchstone/benchmark.h>
#include <touchstone/enumeration_range.h>
#include <touchstone/state.h>
#include <boost/container/flat_set.hpp>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include <memory>
#include <algorithm>
#include <numeric>

namespace touchstone {

class BenchmarkSet {
  static const int kNullBenchmarkId = -1;
 public:
  using Runner = std::function<void(BenchmarkSet&)>;

  BenchmarkSet(std::string&& name, Runner&& runner)
    : _name(std::move(name))
    , _runner(std::move(runner))
  {
  }

  int add(const Benchmark& benchmark) {
    int id = _benchmarks.size();
    auto was_inserted = _benchmarks.insert(benchmark);
    if(!was_inserted.second) {
      std::cerr << "bechmark " << benchmark.name() << " is not unique for benchmark "
                << _name << std::endl;
      std::abort();
    }
    was_inserted.first->set_id(id);
    return id;
  }

  void run() {
    assert(_runner && "runner is not set");
    assert(_num_trials > 0 && "num trials is not set");
    assert(_num_epochs > 0 && "num epochs is not set");

    // run through the benchmark set a single time
    // to invoke callbacks that add each individual
    // benchmark
    State::get_n() = _enumeration_range->begin(); //make sure we use a valid value of n
    _runner(*this);

    // repeatedly invoke the runner function until each benchmark 
    // has been run range_size x num_epochs x num_trials times. 
    // The global random number generator should be identically
    // seeded for every (range_value, trial_id) pair.
    std::random_device random_device;
    for(_epoch_id=0; _epoch_id<_num_epochs; ++_epoch_id) {
      _n        = _enumeration_range->begin();
      int last  = _enumeration_range->end();
      for(; _n < last; _n = _enumeration_range->advance(_n)) {
        State::get_n() = _n;
        auto random_seed = random_device();
        for(auto& benchmark : _benchmarks) {
          _current_benchmark = &benchmark;
          for(int trial_id=0; trial_id<_num_trials; ++trial_id) {
            State::get_random_number_generator().seed(random_seed);
            _runner(*this);
          }
        }
      }
    }
    _current_benchmark = nullptr;
  }

  void record_elapse(double elapse) {
    _current_benchmark->add_result(_n, _epoch_id, elapse);
  }

  void set_enumeration_range(std::shared_ptr<const EnumerationRange>&& enumeration_range) {
{'fraction_non_alphanumeric': 0.12277470841006753, 'fraction_numerical': 0.0020462451401677922, 'mean_word_length': 3.32183908045977, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2305188', 'n_tokens_mistral': 1624, 'n_tokens_neox': 1566, 'n_words': 380}