// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2015 Benoit Jacob <benoitjacob@google.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <iostream>
#include <cstdint>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <fstream>
#include <string>
#include <cmath>
#include <cassert>
#include <cstring>
#include <memory>

#include <Eigen/Core>

using namespace std;

const int default_precision = 4;

// see --only-cubic-sizes
bool only_cubic_sizes = false;

// see --dump-tables
bool dump_tables = false;

uint8_t log2_pot(size_t x) {
  size_t l = 0;
  while (x >>= 1) l++;
  return l;
}

uint16_t compact_size_triple(size_t k, size_t m, size_t n)
{
  return (log2_pot(k) << 8) | (log2_pot(m) << 4) | log2_pot(n);
}

// just a helper to store a triple of K,M,N sizes for matrix product
struct size_triple_t
{
  uint16_t k, m, n;
  size_triple_t() : k(0), m(0), n(0) {}
  size_triple_t(size_t _k, size_t _m, size_t _n) : k(_k), m(_m), n(_n) {}
  size_triple_t(const size_triple_t& o) : k(o.k), m(o.m), n(o.n) {}
  size_triple_t(uint16_t compact)
  {
    k = 1 << ((compact & 0xf00) >> 8);
    m = 1 << ((compact & 0x0f0) >> 4);
    n = 1 << ((compact & 0x00f) >> 0);
  }
  bool is_cubic() const { return k == m && m == n; }
};

ostream& operator<<(ostream& s, const size_triple_t& t)
{
  return s << "(" << t.k << ", " << t.m << ", " << t.n << ")";
}

struct inputfile_entry_t
{
  uint16_t product_size;
  uint16_t pot_block_size;
  size_triple_t nonpot_block_size;
  float gflops;
};

struct inputfile_t
{
  enum class type_t {
    unknown,
    all_pot_sizes,
    default_sizes
  };

  string filename;
  vector<inputfile_entry_t> entries;
  type_t type;

  inputfile_t(const string& fname)
    : filename(fname)
    , type(type_t::unknown)
  {
    ifstream stream(filename);
    if (!stream.is_open()) {
      cerr << "couldn't open input file: " << filename << endl;
      exit(1);
    }
    string line;
    while (getline(stream, line)) {
      if (line.empty()) continue;
      if (line.find("BEGIN MEASUREMENTS ALL POT SIZES") == 0) {
        if (type != type_t::unknown) {
          cerr << "Input file " << filename << " contains redundant BEGIN MEASUREMENTS lines";
          exit(1);
        }
        type = type_t::all_pot_sizes;
        continue;
      }
      if (line.find("BEGIN MEASUREMENTS DEFAULT SIZES") == 0) {
        if (type != type_t::unknown) {
          cerr << "Input file " << filename << " contains redundant BEGIN MEASUREMENTS lines";
          exit(1);
        }
        type = type_t::default_sizes;
        continue;
      }
      

      if (type == type_t::unknown) {
        continue;
      }
      switch(type) {
        case type_t::all_pot_sizes: {
          unsigned int product_size, block_size;
          float gflops;
          int sscanf_result =
            sscanf(line.c_str(), "%x %x %f",
                   &product_size,
                   &block_size,
                   &gflops);
          if (3 != sscanf_result ||
              !product_size ||
              product_size > 0xfff ||
              !block_size ||
              block_size > 0xfff ||
              !isfinite(gflops))
          {
            cerr << "ill-formed input file: " << filename << endl;
            cerr << "offending line:" << endl << line << endl;
            exit(1);
          }
          if (only_cubic_sizes && !size_triple_t(product_size).is_cubic()) {
            continue;
          }
          inputfile_entry_t entry;
          entry.product_size = uint16_t(product_size);
          entry.pot_block_size = uint16_t(block_size);
          entry.gflops = gflops;
          entries.push_back(entry);
          break;
        }
        case type_t::default_sizes: {
          unsigned int product_size;
          float gflops;
          int bk, bm, bn;
          int sscanf_result =
            sscanf(line.c_str(), "%x default(%d, %d, %d) %f",
                   &product_size,
                   &bk, &bm, &bn,
                   &gflops);
          if (5 != sscanf_result ||
              !product_size ||
              product_size > 0xfff ||
              !isfinite(gflops))
          {
            cerr << "ill-formed input file: " << filename << endl;
            cerr << "offending line:" << endl << line << endl;
            exit(1);
          }
          if (only_cubic_sizes && !size_triple_t(product_size).is_cubic()) {
            continue;
          }
          inputfile_entry_t entry;
          entry.product_size = uint16_t(product_size);
          entry.pot_block_size = 0;
          entry.nonpot_block_size = size_triple_t(bk, bm, bn);
          entry.gflops = gflops;
          entries.push_back(entry);
          break;
        }
        
        default:
          break;
      }
    }
    stream.close();
    if (type == type_t::unknown) {
      cerr << "Unrecognized input file " << filename << endl;
      exit(1);
    }
    if (entries.empty()) {
      cerr << "didn't find any measurements in input file: " << filename << endl;
      exit(1);
    }
  }
};

struct preprocessed_inputfile_entry_t
{
  uint16_t product_size;
  uint16_t block_size;

  float efficiency;
};

bool lower_efficiency(const preprocessed_inputfile_entry_t& e1, const preprocessed_inputfile_entry_t& e2)
{
  return e1.efficiency < e2.efficiency;
}

struct preprocessed_inputfile_t
{
  string filename;
  vector<preprocessed_inputfile_entry_t> entries;

  preprocessed_inputfile_t(const inputfile_t& inputfile)
    : filename(inputfile.filename)
  {
    if (inputfile.type != inputfile_t::type_t::all_pot_sizes) {
      abort();
    }
    auto it = inputfile.entries.begin();
    auto it_first_with_given_product_size = it;
    while (it != inputfile.entries.end()) {
      ++it;
      if (it == inputfile.entries.end() ||
        it->product_size != it_first_with_given_product_size->product_size)
      {
        import_input_file_range_one_product_size(it_first_with_given_product_size, it);
        it_first_with_given_product_size = it;
      }
    }
  }

private:
  void import_input_file_range_one_product_size(
    const vector<inputfile_entry_t>::const_iterator& begin,
    const vector<inputfile_entry_t>::const_iterator& end)
  {
    uint16_t product_size = begin->product_size;
    float max_gflops = 0.0f;
    for (auto it = begin; it != end; ++it) {
      if (it->product_size != product_size) {
        cerr << "Unexpected ordering of entries in " << filename << endl;
        cerr << "(Expected all entries for product size " << hex << product_size << dec << " to be grouped)" << endl;
        exit(1);
      }
      max_gflops = max(max_gflops, it->gflops);
    }
    for (auto it = begin; it != end; ++it) {
      preprocessed_inputfile_entry_t entry;
      entry.product_size = it->product_size;
      entry.block_size = it->pot_block_size;
      entry.efficiency = it->gflops / max_gflops;
      entries.push_back(entry);
    }
  }
};

void check_all_files_in_same_exact_order(
       const vector<preprocessed_inputfile_t>& preprocessed_inputfiles)
{
  if (preprocessed_inputfiles.empty()) {
    return;
  }

  const preprocessed_inputfile_t& first_file = preprocessed_inputfiles[0];
  const size_t num_entries = first_file.entries.size();

  for (size_t i = 0; i < preprocessed_inputfiles.size(); i++) {
    if (preprocessed_inputfiles[i].entries.size() != num_entries) {
      cerr << "these files have different number of entries: "
           << preprocessed_inputfiles[i].filename
           << " and "
           << first_file.filename
           << endl;
      exit(1);
    }
  }

  for (size_t entry_index = 0; entry_index < num_entries; entry_index++) {
    const uint16_t entry_product_size = first_file.entries[entry_index].product_size;
    const uint16_t entry_block_size = first_file.entries[entry_index].block_size;
    for (size_t file_index = 0; file_index < preprocessed_inputfiles.size(); file_index++) {
      const preprocessed_inputfile_t& cur_file = preprocessed_inputfiles[file_index];
      if (cur_file.entries[entry_index].product_size != entry_product_size ||
          cur_file.entries[entry_index].block_size != entry_block_size)
      {
        cerr << "entries not in same order between these files: "
             << first_file.filename
             << " and "
             << cur_file.filename
             << endl;
        exit(1);
      }
    }
  }
}

float efficiency_of_subset(
        const vector<preprocessed_inputfile_t>& preprocessed_inputfiles,
        const vector<size_t>& subset)
{
  if (subset.size() <= 1) {
    return 1.0f;
  }
  const preprocessed_inputfile_t& first_file = preprocessed_inputfiles[subset[0]];
  const size_t num_entries = first_file.entries.size();
  float efficiency = 1.0f;
  size_t entry_index = 0;
  size_t first_entry_index_with_this_product_size = 0;
  uint16_t product_size = first_file.entries[0].product_size;
  while (entry_index < num_entries) {
    ++entry_index;
    if (entry_index == num_entries ||
        first_file.entries[entry_index].product_size != product_size)
    {
      float efficiency_this_product_size = 0.0f;
      for (size_t e = first_entry_index_with_this_product_size; e < entry_index; e++) {
        float efficiency_this_entry = 1.0f;
        for (auto i = subset.begin(); i != subset.end(); ++i) {
          efficiency_this_entry = min(efficiency_this_entry, preprocessed_inputfiles[*i].entries[e].efficiency);
        }
        efficiency_this_product_size = max(efficiency_this_product_size, efficiency_this_entry);
      }
      efficiency = min(efficiency, efficiency_this_product_size);
      if (entry_index < num_entries) {
        first_entry_index_with_this_product_size = entry_index;
        product_size = first_file.entries[entry_index].product_size;
      }
    }
  }

  return efficiency;
}

void dump_table_for_subset(
        const vector<preprocessed_inputfile_t>& preprocessed_inputfiles,
        const vector<size_t>& subset)
{
  const preprocessed_inputfile_t& first_file = preprocessed_inputfiles[subset[0]];
  const size_t num_entries = first_file.entries.size();
  size_t entry_index = 0;
  size_t first_entry_index_with_this_product_size = 0;
  uint16_t product_size = first_file.entries[0].product_size;
  size_t i = 0;
  size_triple_t min_product_size(first_file.entries.front().product_size);
  size_triple_t max_product_size(first_file.entries.back().product_size);
  if (!min_product_size.is_cubic() || !max_product_size.is_cubic()) {
    abort();
  }
  if (only_cubic_sizes) {
    cerr << "Can't generate tables with --only-cubic-sizes." << endl;
    abort();
  }
  cout << "struct LookupTable {" << endl;
  cout << "  static const size_t BaseSize = " << min_product_size.k << ";" << endl;
  const size_t NumSizes = log2_pot(max_product_size.k / min_product_size.k) + 1;
  const size_t TableSize = NumSizes * NumSizes * NumSizes;
  cout << "  static const size_t NumSizes = " << NumSizes << ";" << endl;
  cout << "  static const unsigned short* Data() {" << endl;
  cout << "    static const unsigned short data[" << TableSize << "] = {";
  while (entry_index < num_entries) {
    ++entry_index;
    if (entry_index == num_entries ||
        first_file.entries[entry_index].product_size != product_size)
    {
      float best_efficiency_this_product_size = 0.0f;
      uint16_t best_block_size_this_product_size = 0;
      for (size_t e = first_entry_index_with_this_product_size; e < entry_index; e++) {
        float efficiency_this_entry = 1.0f;
        for (auto i = subset.begin(); i != subset.end(); ++i) {
          efficiency_this_entry = min(efficiency_this_entry, preprocessed_inputfiles[*i].entries[e].efficiency);
        }
        if (efficiency_this_entry > best_efficiency_this_product_size) {
          best_efficiency_this_product_size = efficiency_this_entry;
          best_block_size_this_product_size = first_file.entries[e].block_size;
        }
      }
      if ((i++) % NumSizes) {
        cout << " ";
      } else {
        cout << endl << "      ";
      }
      cout << "0x" << hex << best_block_size_this_product_size << dec;
      if (entry_index < num_entries) {
        cout << ",";
        first_entry_index_with_this_product_size = entry_index;
        product_size = first_file.entries[entry_index].product_size;
      }
    }
  }
  if (i != TableSize) {
    cerr << endl << "Wrote " << i << " table entries, expected " << TableSize << endl;
    abort();
  }
  cout << endl << "    };" << endl;
  cout << "    return data;" << endl;
  cout << "  }" << endl;
  cout << "};" << endl;
}

float efficiency_of_partition(
        const vector<preprocessed_inputfile_t>& preprocessed_inputfiles,
        const vector<vector<size_t>>& partition)
{
  float efficiency = 1.0f;
  for (auto s = partition.begin(); s != partition.end(); ++s) {
    efficiency = min(efficiency, efficiency_of_subset(preprocessed_inputfiles, *s));
  }
  return efficiency;
}

void make_first_subset(size_t subset_size, vector<size_t>& out_subset, size_t set_size)
{
  assert(subset_size >= 1 && subset_size <= set_size);
  out_subset.resize(subset_size);
  for (size_t i = 0; i < subset_size; i++) {
    out_subset[i] = i;
  }
}

bool is_last_subset(const vector<size_t>& subset, size_t set_size)
{
  return subset[0] == set_size - subset.size();
}

void next_subset(vector<size_t>& inout_subset, size_t set_size)
{
  if (is_last_subset(inout_subset, set_size)) {
    cerr << "iterating past the last subset" << endl;
    abort();
  }
  size_t i = 1;
  while (inout_subset[inout_subset.size() - i] == set_size - i) {
    i++;
    assert(i <= inout_subset.size());
  }
  size_t first_index_to_change = inout_subset.size() - i;
  inout_subset[first_index_to_change]++;
  size_t p = inout_subset[first_index_to_change];
  for (size_t j = first_index_to_change + 1; j < inout_subset.size(); j++) {
    inout_subset[j] = ++p;
  }
}

const size_t number_of_subsets_limit = 100;
const size_t always_search_subsets_of_size_at_least = 2;

bool is_number_of_subsets_feasible(size_t n, size_t p)
{ 
  assert(n>0 && p>0 && p<=n);
  uint64_t numerator = 1, denominator = 1;
  for (size_t i = 0; i < p; i++) {
    numerator *= n - i;
    denominator *= i + 1;
    if (numerator > denominator * number_of_subsets_limit) {
      return false;
    }
  }
  return true;
}

size_t max_feasible_subset_size(size_t n)
{
  assert(n > 0);
  const size_t minresult = min<size_t>(n-1, always_search_subsets_of_size_at_least);
  for (size_t p = 1; p <= n - 1; p++) {
    if (!is_number_of_subsets_feasible(n, p+1)) {
      return max(p, minresult);
    }
  }
  return n - 1;
}

void find_subset_with_efficiency_higher_than(
       const vector<preprocessed_inputfile_t>& preprocessed_inputfiles,
       float required_efficiency_to_beat,
       vector<size_t>& inout_remainder,
       vector<size_t>& out_subset)
{
  out_subset.resize(0);

  if (required_efficiency_to_beat >= 1.0f) {
    cerr << "can't beat efficiency 1." << endl;
    abort();
  }

  while (!inout_remainder.empty()) {

    vector<size_t> candidate_indices(inout_remainder.size());
    for (size_t i = 0; i < candidate_indices.size(); i++) {
      candidate_indices[i] = i;
    }

    size_t candidate_indices_subset_size = max_feasible_subset_size(candidate_indices.size());
    while (candidate_indices_subset_size >= 1) {
      vector<size_t> candidate_indices_subset;
      make_first_subset(candidate_indices_subset_size,
                        candidate_indices_subset,
                        candidate_indices.size());

      vector<size_t> best_candidate_indices_subset;
      float best_efficiency = 0.0f;
      vector<size_t> trial_subset = out_subset;
      trial_subset.resize(out_subset.size() + candidate_indices_subset_size);
      while (true)
      {
        for (size_t i = 0; i < candidate_indices_subset_size; i++) {
          trial_subset[out_subset.size() + i] = inout_remainder[candidate_indices_subset[i]];
        }
        
        float trial_efficiency = efficiency_of_subset(preprocessed_inputfiles, trial_subset);
        if (trial_efficiency > best_efficiency) {
          best_efficiency = trial_efficiency;
          best_candidate_indices_subset = candidate_indices_subset;
        }
        if (is_last_subset(candidate_indices_subset, candidate_indices.size())) {
          break;
        }
        next_subset(candidate_indices_subset, candidate_indices.size());
      }
       
      if (best_efficiency > required_efficiency_to_beat) {
        for (size_t i = 0; i < best_candidate_indices_subset.size(); i++) {
          candidate_indices[i] = candidate_indices[best_candidate_indices_subset[i]];
        }
        candidate_indices.resize(best_candidate_indices_subset.size());
      }
      candidate_indices_subset_size--;
    }
      
    size_t candidate_index = candidate_indices[0];
    auto candidate_iterator = inout_remainder.begin() + candidate_index;
    vector<size_t> trial_subset = out_subset;

    trial_subset.push_back(*candidate_iterator);
    float trial_efficiency = efficiency_of_subset(preprocessed_inputfiles, trial_subset);
    if (trial_efficiency > required_efficiency_to_beat) {
      out_subset.push_back(*candidate_iterator);
      inout_remainder.erase(candidate_iterator);
    } else {
      break;
    }
  }
}

void find_partition_with_efficiency_higher_than(
       const vector<preprocessed_inputfile_t>& preprocessed_inputfiles,
       float required_efficiency_to_beat,
       vector<vector<size_t>>& out_partition)
{
  out_partition.resize(0);

  vector<size_t> remainder;
  for (size_t i = 0; i < preprocessed_inputfiles.size(); i++) {
    remainder.push_back(i);
  }

  while (!remainder.empty()) {
    vector<size_t> new_subset;
    find_subset_with_efficiency_higher_than(
      preprocessed_inputfiles,
      required_efficiency_to_beat,
      remainder,
      new_subset);
    out_partition.push_back(new_subset);
  }
}

void print_partition(
       const vector<preprocessed_inputfile_t>& preprocessed_inputfiles,
       const vector<vector<size_t>>& partition)
{
  float efficiency = efficiency_of_partition(preprocessed_inputfiles, partition);
  cout << "Partition into " << partition.size() << " subsets for " << efficiency * 100.0f << "% efficiency"  << endl;
  for (auto subset = partition.begin(); subset != partition.end(); ++subset) {
    cout << "  Subset " << (subset - partition.begin())
         << ", efficiency " << efficiency_of_subset(preprocessed_inputfiles, *subset) * 100.0f << "%:"
         << endl;
    for (auto file = subset->begin(); file != subset->end(); ++file) {
      cout << "    " << preprocessed_inputfiles[*file].filename << endl;
    }
    if (dump_tables) {
      cout << "  Table:" << endl;
      dump_table_for_subset(preprocessed_inputfiles, *subset);
    }
  }
  cout << endl;
}

struct action_t
{
  virtual const char* invokation_name() const { abort(); return nullptr; }
  virtual void run(const vector<string>&) const { abort(); }
  virtual ~action_t() {}
};

struct partition_action_t : action_t
{
  virtual const char* invokation_name() const override { return "partition"; }
  virtual void run(const vector<string>& input_filenames) const override
  {
    vector<preprocessed_inputfile_t> preprocessed_inputfiles;

    if (input_filenames.empty()) {
      cerr << "The " << invokation_name() << " action needs a list of input files." << endl;
      exit(1);
    }

    for (auto it = input_filenames.begin(); it != input_filenames.end(); ++it) {
      inputfile_t inputfile(*it);
      switch (inputfile.type) {
        case inputfile_t::type_t::all_pot_sizes:
          preprocessed_inputfiles.emplace_back(inputfile);
          break;
        case inputfile_t::type_t::default_sizes:
          cerr << "The " << invokation_name() << " action only uses measurements for all pot sizes, and "
               << "has no use for " << *it << " which contains measurements for default sizes." << endl;
          exit(1);
          break;
        default:
          cerr << "Unrecognized input file: " << *it << endl;
          exit(1);
      }
    }

    check_all_files_in_same_exact_order(preprocessed_inputfiles);

    float required_efficiency_to_beat = 0.0f;
    vector<vector<vector<size_t>>> partitions;
    cerr << "searching for partitions...\r" << flush;
    while (true)
    {
      vector<vector<size_t>> partition;
      find_partition_with_efficiency_higher_than(
        preprocessed_inputfiles,
        required_efficiency_to_beat,
        partition);
      float actual_efficiency = efficiency_of_partition(preprocessed_inputfiles, partition);
      cerr << "partition " << preprocessed_inputfiles.size() << " files into " << partition.size()
           << " subsets for " << 100.0f * actual_efficiency
           << " % efficiency"
           << "                  \r" << flush;
      partitions.push_back(partition);
      if (partition.size() == preprocessed_inputfiles.size() || actual_efficiency == 1.0f) {
        break;
      }
      required_efficiency_to_beat = actual_efficiency;
    }
    cerr << "                                                                  " << endl;
    while (true) {
      bool repeat = false;
      for (size_t i = 0; i < partitions.size() - 1; i++) {
        if (partitions[i].size() >= partitions[i+1].size()) {
          partitions.erase(partitions.begin() + i);
          repeat = true;
          break;
        }
      }
      if (!repeat) {
        break;
      }
    }
    for (auto it = partitions.begin(); it != partitions.end(); ++it) {
      print_partition(preprocessed_inputfiles, *it);
    }
  }
};

struct evaluate_defaults_action_t : action_t
{
  struct results_entry_t {
    uint16_t product_size;
    size_triple_t default_block_size;
    uint16_t best_pot_block_size;
    float default_gflops;
    float best_pot_gflops;
    float default_efficiency;
  };
  friend ostream& operator<<(ostream& s, const results_entry_t& entry)
  {
    return s
      << "Product size " << size_triple_t(entry.product_size)
      << ": default block size " << entry.default_block_size
      << " -> " << entry.default_gflops
      << " GFlop/s = " << entry.default_efficiency * 100.0f << " %"
      << " of best POT block size " << size_triple_t(entry.best_pot_block_size)
      << " -> " << entry.best_pot_gflops
      << " GFlop/s" << dec;
  }
  static bool lower_efficiency(const results_entry_t& e1, const results_entry_t& e2) {
    return e1.default_efficiency < e2.default_efficiency;
  }
  virtual const char* invokation_name() const override { return "evaluate-defaults"; }
  void show_usage_and_exit() const
  {
    cerr << "usage: " << invokation_name() << " default-sizes-data all-pot-sizes-data" << endl;
    cerr << "checks how well the performance with default sizes compares to the best "
         << "performance measured over all POT sizes." << endl;
    exit(1);
  }
  virtual void run(const vector<string>& input_filenames) const override
  {
    if (input_filenames.size() != 2) {
      show_usage_and_exit();
    }
    inputfile_t inputfile_default_sizes(input_filenames[0]);
    inputfile_t inputfile_all_pot_sizes(input_filenames[1]);
    if (inputfile_default_sizes.type != inputfile_t::type_t::default_sizes) {
      cerr << inputfile_default_sizes.filename << " is not an input file with default sizes." << endl;
      show_usage_and_exit();
    }
    if (inputfile_all_pot_sizes.type != inputfile_t::type_t::all_pot_sizes) {
      cerr << inputfile_all_pot_sizes.filename << " is not an input file with all POT sizes." << endl;
      show_usage_and_exit();
    }
    vector<results_entry_t> results;
    vector<results_entry_t> cubic_results;
    
    uint16_t product_size = 0;
    auto it_all_pot_sizes = inputfile_all_pot_sizes.entries.begin();
    for (auto it_default_sizes = inputfile_default_sizes.entries.begin();
         it_default_sizes != inputfile_default_sizes.entries.end();
         ++it_default_sizes)
    {
      if (it_default_sizes->product_size == product_size) {
        continue;
      }
      product_size = it_default_sizes->product_size;
      while (it_all_pot_sizes != inputfile_all_pot_sizes.entries.end() &&
             it_all_pot_sizes->product_size != product_size)
      {
        ++it_all_pot_sizes;
      }
      if (it_all_pot_sizes == inputfile_all_pot_sizes.entries.end()) {
        break;
      }
      uint16_t best_pot_block_size = 0;
      float best_pot_gflops = 0;
      for (auto it = it_all_pot_sizes;
           it != inputfile_all_pot_sizes.entries.end() && it->product_size == product_size;
           ++it)
      {
        if (it->gflops > best_pot_gflops) {
          best_pot_gflops = it->gflops;
          best_pot_block_size = it->pot_block_size;
        }
      }
      results_entry_t entry;
      entry.product_size = product_size;
      entry.default_block_size = it_default_sizes->nonpot_block_size;
      entry.best_pot_block_size = best_pot_block_size;
      entry.default_gflops = it_default_sizes->gflops;
      entry.best_pot_gflops = best_pot_gflops;
      entry.default_efficiency = entry.default_gflops / entry.best_pot_gflops;
      results.push_back(entry);

      size_triple_t t(product_size);
      if (t.k == t.m && t.m == t.n) {
        cubic_results.push_back(entry);
      }
    }

    cout << "All results:" << endl;
    for (auto it = results.begin(); it != results.end(); ++it) {
      cout << *it << endl;
    }
    cout << endl;

    sort(results.begin(), results.end(), lower_efficiency);
    
    const size_t n = min<size_t>(20, results.size());
    cout << n << " worst results:" << endl;
    for (size_t i = 0; i < n; i++) {
      cout << results[i] << endl;
    }
    cout << endl;

    cout << "cubic results:" << endl;
    for (auto it = cubic_results.begin(); it != cubic_results.end(); ++it) {
      cout << *it << endl;
    }
    cout << endl;

    sort(cubic_results.begin(), cubic_results.end(), lower_efficiency);
    
    cout.precision(2);
    vector<float> a = {0.5f, 0.20f, 0.10f, 0.05f, 0.02f, 0.01f};
    for (auto it = a.begin(); it != a.end(); ++it) {
      size_t n = min(results.size() - 1, size_t(*it * results.size()));
      cout << (100.0f * n / (results.size() - 1))
           << " % of product sizes have default efficiency <= "
           << 100.0f * results[n].default_efficiency << " %" << endl;
    }
    cout.precision(default_precision);
  }
};


void show_usage_and_exit(int argc, char* argv[],
                         const vector<unique_ptr<action_t>>& available_actions)
{
  cerr << "usage: " << argv[0] << " <action> [options...] <input files...>" << endl;
  cerr << "available actions:" << endl;
  for (auto it = available_actions.begin(); it != available_actions.end(); ++it) {
    cerr << "  " << (*it)->invokation_name() << endl;
  } 
  cerr << "the input files should each contain an output of benchmark-blocking-sizes" << endl;
  exit(1);
}

int main(int argc, char* argv[])
{
  cout.precision(default_precision);
  cerr.precision(default_precision);

  vector<unique_ptr<action_t>> available_actions;
  available_actions.emplace_back(new partition_action_t);
  available_actions.emplace_back(new evaluate_defaults_action_t);

  vector<string> input_filenames;

  action_t* action = nullptr;

  if (argc < 2) {
    show_usage_and_exit(argc, argv, available_actions);
  }
  for (int i = 1; i < argc; i++) {
    bool arg_handled = false;
    // Step 1. Try to match action invocation names.
    for (auto it = available_actions.begin(); it != available_actions.end(); ++it) {
      if (!strcmp(argv[i], (*it)->invokation_name())) {
        if (!action) {
          action = it->get();
          arg_handled = true;
          break;
        } else {
          cerr << "can't specify more than one action!" << endl;
          show_usage_and_exit(argc, argv, available_actions);
        }
      }
    }
    if (arg_handled) {
      continue;
    }
    // Step 2. Try to match option names.
    if (argv[i][0] == '-') {
      if (!strcmp(argv[i], "--only-cubic-sizes")) {
        only_cubic_sizes = true;
        arg_handled = true;
      }
      if (!strcmp(argv[i], "--dump-tables")) {
        dump_tables = true;
        arg_handled = true;
      }
      if (!arg_handled) {
        cerr << "Unrecognized option: " << argv[i] << endl;
        show_usage_and_exit(argc, argv, available_actions);
      }
    }
    if (arg_handled) {
      continue;
    }
    // Step 3. Default to interpreting args as input filenames.
    input_filenames.emplace_back(argv[i]);
  }

  if (dump_tables && only_cubic_sizes) {
    cerr << "Incompatible options: --only-cubic-sizes and --dump-tables." << endl;
    show_usage_and_exit(argc, argv, available_actions);
  }

  if (!action) {
    show_usage_and_exit(argc, argv, available_actions);
  }

  action->run(input_filenames);
}
