<commit_before>#pragma once

#include "abstract_tuner.hpp"
#include "countable_set.hpp"

#include <random>

namespace autotune {
namespace tuners {

template <typename R, typename... Args>
class line_search : public abstract_tuner<countable_set, R, Args...> {
private:
  // autotune::abstract_kernel<R, cppjit::detail::pack<Args...>> &f;
  // countable_set &parameters;
  size_t max_iterations;
  size_t restarts;

public:
  line_search(autotune::abstract_kernel<R, cppjit::detail::pack<Args...>> &f,
              countable_set &parameters, size_t max_iterations, size_t restarts)
      : abstract_tuner<countable_set, R, Args...>(f, parameters),
        max_iterations(max_iterations), restarts(restarts) {}

  countable_set tune(Args &... args) {

    parameter_value_set original_values = this->f.get_parameter_values();

    // set to initial guess (or whatever the parameter type is doing)
    for (size_t i = 0; i < this->parameters.size(); i++) {
      this->parameters[i]->set_min();
    }

    // evaluate initial guess
    bool is_valid = true;
    countable_set optimal_parameters = this->parameters;

    double optimal_duration = -1.0;
    bool first = true;

    size_t counter = 0;
    size_t cur_index = 0;
    while (counter < max_iterations) {
      if (this->verbose) {
        std::cout << "current parameter index: " << cur_index << std::endl;
      }

      auto &p = this->parameters[cur_index];
      // p->set_index(0);
      p->set_initial();
      while (true) {

        // if a valid new index value was found, test it
        double duration = this->evaluate(is_valid, args...);
        if (is_valid && (first || duration < optimal_duration)) {
          first = false;
          optimal_parameters = this->parameters;
          optimal_duration = duration;
          if (this->verbose) {
            this->report_verbose("new best kernel", optimal_duration,
                                 this->parameters);
          }
        }
        if (!p->next()) {
          break;
        }
      }

      p->set_initial();
      // do not evaluate resetted value
      while (p->prev()) {

        // if a valid new index value was found, test it
        double duration = this->evaluate(is_valid, args...);
        if (is_valid && (first || duration < optimal_duration)) {
          first = false;
          optimal_parameters = this->parameters;
          optimal_duration = duration;
          if (this->verbose) {
            this->report_verbose("new best kernel", optimal_duration,
                                 this->parameters);
          }
        }
      }
      cur_index = (cur_index + 1) % this->parameters.size();
      counter += 1;
      this->parameters = optimal_parameters;
    }
<commit_msg>improved line search<commit_after>#pragma once

#include "abstract_tuner.hpp"
#include "countable_set.hpp"

#include <random>

namespace autotune {
namespace tuners {

template <typename R, typename... Args>
class line_search : public abstract_tuner<countable_set, R, Args...> {
private:
  // autotune::abstract_kernel<R, cppjit::detail::pack<Args...>> &f;
  // countable_set &parameters;
  size_t max_iterations;
  size_t restarts;

  void evaluate_parameter_set(bool &first, countable_set &optimal_parameters,
                              double &optimal_duration, Args &... args) {
    // if a valid new index value was found, test it
    bool is_valid = true;
    double duration = this->evaluate(is_valid, args...);
    if (is_valid && (first || duration < optimal_duration)) {
      first = false;
      optimal_parameters = this->parameters;
      optimal_duration = duration;
      if (this->verbose) {
        this->report_verbose("new best kernel", optimal_duration,
                             this->parameters);
      }
    }
  }

public:
  line_search(autotune::abstract_kernel<R, cppjit::detail::pack<Args...>> &f,
              countable_set &parameters, size_t max_iterations, size_t restarts)
      : abstract_tuner<countable_set, R, Args...>(f, parameters),
        max_iterations(max_iterations), restarts(restarts) {}

  countable_set tune(Args &... args) {

    parameter_value_set original_values = this->f.get_parameter_values();

    // set to initial guess (or whatever the parameter type is doing)
    for (size_t i = 0; i < this->parameters.size(); i++) {
      this->parameters[i]->set_min();
    }

    // evaluate initial guess
    countable_set optimal_parameters = this->parameters;

    double optimal_duration = -1.0;
    bool first = true;

    size_t counter = 0;
    size_t cur_index = 0;
    while (counter < max_iterations) {
      if (this->verbose) {
        std::cout << "current parameter index: " << cur_index << std::endl;
      }

      auto &p = this->parameters[cur_index];
      std::string old_value = p->get_value();
      p->set_initial();

      if (first || p->get_value().compare(old_value) != 0) {
        evaluate_parameter_set(first, optimal_parameters, optimal_duration,
                               args...);
      }

      while (p->next()) {
        if (first || p->get_value().compare(old_value) != 0) {
          evaluate_parameter_set(first, optimal_parameters, optimal_duration,
                                 args...);
        }
      }

      p->set_initial();
      // do not evaluate resetted value
      while (p->prev()) {
        if (first || p->get_value().compare(old_value) != 0) {
          evaluate_parameter_set(first, optimal_parameters, optimal_duration,
                                 args...);
        }
      }
      cur_index = (cur_index + 1) % this->parameters.size();
      counter += 1;
      this->parameters = optimal_parameters;
    }

{'fraction_non_alphanumeric': 0.12790697674418605, 'fraction_numerical': 0.003171247357293869, 'mean_word_length': 2.4178205900060203, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6705460', 'n_tokens_mistral': 1711, 'n_tokens_neox': 1668, 'n_words': 394}