analyze-blocking-sizes.cpp File Reference
#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>

Classes

struct  size_triple_t
 
struct  inputfile_entry_t
 
struct  inputfile_t
 
struct  preprocessed_inputfile_entry_t
 
struct  preprocessed_inputfile_t
 
struct  action_t
 
struct  partition_action_t
 
struct  evaluate_defaults_action_t
 
struct  evaluate_defaults_action_t::results_entry_t
 

Functions

uint8_t log2_pot (size_t x)
 
uint16_t compact_size_triple (size_t k, size_t m, size_t n)
 
ostream & operator<< (ostream &s, const size_triple_t &t)
 
bool lower_efficiency (const preprocessed_inputfile_entry_t &e1, const preprocessed_inputfile_entry_t &e2)
 
void check_all_files_in_same_exact_order (const vector< preprocessed_inputfile_t > &preprocessed_inputfiles)
 
float efficiency_of_subset (const vector< preprocessed_inputfile_t > &preprocessed_inputfiles, const vector< size_t > &subset)
 
void dump_table_for_subset (const vector< preprocessed_inputfile_t > &preprocessed_inputfiles, const vector< size_t > &subset)
 
float efficiency_of_partition (const vector< preprocessed_inputfile_t > &preprocessed_inputfiles, const vector< vector< size_t >> &partition)
 
void make_first_subset (size_t subset_size, vector< size_t > &out_subset, size_t set_size)
 
bool is_last_subset (const vector< size_t > &subset, size_t set_size)
 
void next_subset (vector< size_t > &inout_subset, size_t set_size)
 
bool is_number_of_subsets_feasible (size_t n, size_t p)
 
size_t max_feasible_subset_size (size_t n)
 
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)
 
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)
 
void print_partition (const vector< preprocessed_inputfile_t > &preprocessed_inputfiles, const vector< vector< size_t >> &partition)
 
void show_usage_and_exit (int argc, char *argv[], const vector< unique_ptr< action_t >> &available_actions)
 
int main (int argc, char *argv[])
 

Variables

const int default_precision = 4
 
bool only_cubic_sizes = false
 
bool dump_tables = false
 
const size_t number_of_subsets_limit = 100
 
const size_t always_search_subsets_of_size_at_least = 2
 

Function Documentation

◆ check_all_files_in_same_exact_order()

void check_all_files_in_same_exact_order ( const vector< preprocessed_inputfile_t > &  preprocessed_inputfiles)
215  {
216  if (preprocessed_inputfiles.empty()) {
217  return;
218  }
219 
220  const preprocessed_inputfile_t& first_file = preprocessed_inputfiles[0];
221  const size_t num_entries = first_file.entries.size();
222 
223  for (size_t i = 0; i < preprocessed_inputfiles.size(); i++) {
224  if (preprocessed_inputfiles[i].entries.size() != num_entries) {
225  cerr << "these files have different number of entries: " << preprocessed_inputfiles[i].filename << " and "
226  << first_file.filename << endl;
227  exit(1);
228  }
229  }
230 
231  for (size_t entry_index = 0; entry_index < num_entries; entry_index++) {
232  const uint16_t entry_product_size = first_file.entries[entry_index].product_size;
233  const uint16_t entry_block_size = first_file.entries[entry_index].block_size;
234  for (size_t file_index = 0; file_index < preprocessed_inputfiles.size(); file_index++) {
235  const preprocessed_inputfile_t& cur_file = preprocessed_inputfiles[file_index];
236  if (cur_file.entries[entry_index].product_size != entry_product_size ||
237  cur_file.entries[entry_index].block_size != entry_block_size) {
238  cerr << "entries not in same order between these files: " << first_file.filename << " and " << cur_file.filename
239  << endl;
240  exit(1);
241  }
242  }
243  }
244 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
std::uint16_t uint16_t
Definition: Meta.h:38
Definition: analyze-blocking-sizes.cpp:173
string filename
Definition: analyze-blocking-sizes.cpp:174
vector< preprocessed_inputfile_entry_t > entries
Definition: analyze-blocking-sizes.cpp:175

References preprocessed_inputfile_t::entries, preprocessed_inputfile_t::filename, and i.

Referenced by partition_action_t::run().

◆ compact_size_triple()

uint16_t compact_size_triple ( size_t  k,
size_t  m,
size_t  n 
)
40  {
41  return (log2_pot(k) << 8) | (log2_pot(m) << 4) | log2_pot(n);
42 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
uint8_t log2_pot(size_t x)
Definition: analyze-blocking-sizes.cpp:34
int * m
Definition: level2_cplx_impl.h:294
char char char int int * k
Definition: level2_impl.h:374

References k, log2_pot(), m, and n.

◆ dump_table_for_subset()

void dump_table_for_subset ( const vector< preprocessed_inputfile_t > &  preprocessed_inputfiles,
const vector< size_t > &  subset 
)
280  {
281  const preprocessed_inputfile_t& first_file = preprocessed_inputfiles[subset[0]];
282  const size_t num_entries = first_file.entries.size();
283  size_t entry_index = 0;
284  size_t first_entry_index_with_this_product_size = 0;
285  uint16_t product_size = first_file.entries[0].product_size;
286  size_t i = 0;
287  size_triple_t min_product_size(first_file.entries.front().product_size);
288  size_triple_t max_product_size(first_file.entries.back().product_size);
289  if (!min_product_size.is_cubic() || !max_product_size.is_cubic()) {
290  abort();
291  }
292  if (only_cubic_sizes) {
293  cerr << "Can't generate tables with --only-cubic-sizes." << endl;
294  abort();
295  }
296  cout << "struct LookupTable {" << endl;
297  cout << " static const size_t BaseSize = " << min_product_size.k << ";" << endl;
298  const size_t NumSizes = log2_pot(max_product_size.k / min_product_size.k) + 1;
299  const size_t TableSize = NumSizes * NumSizes * NumSizes;
300  cout << " static const size_t NumSizes = " << NumSizes << ";" << endl;
301  cout << " static const unsigned short* Data() {" << endl;
302  cout << " static const unsigned short data[" << TableSize << "] = {";
303  while (entry_index < num_entries) {
304  ++entry_index;
305  if (entry_index == num_entries || first_file.entries[entry_index].product_size != product_size) {
306  float best_efficiency_this_product_size = 0.0f;
307  uint16_t best_block_size_this_product_size = 0;
308  for (size_t e = first_entry_index_with_this_product_size; e < entry_index; e++) {
309  float efficiency_this_entry = 1.0f;
310  for (auto i = subset.begin(); i != subset.end(); ++i) {
311  efficiency_this_entry = min(efficiency_this_entry, preprocessed_inputfiles[*i].entries[e].efficiency);
312  }
313  if (efficiency_this_entry > best_efficiency_this_product_size) {
314  best_efficiency_this_product_size = efficiency_this_entry;
315  best_block_size_this_product_size = first_file.entries[e].block_size;
316  }
317  }
318  if ((i++) % NumSizes) {
319  cout << " ";
320  } else {
321  cout << endl << " ";
322  }
323  cout << "0x" << hex << best_block_size_this_product_size << dec;
324  if (entry_index < num_entries) {
325  cout << ",";
326  first_entry_index_with_this_product_size = entry_index;
327  product_size = first_file.entries[entry_index].product_size;
328  }
329  }
330  }
331  if (i != TableSize) {
332  cerr << endl << "Wrote " << i << " table entries, expected " << TableSize << endl;
333  abort();
334  }
335  cout << endl << " };" << endl;
336  cout << " return data;" << endl;
337  cout << " }" << endl;
338  cout << "};" << endl;
339 }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
bool only_cubic_sizes
Definition: analyze-blocking-sizes.cpp:29
#define min(a, b)
Definition: datatypes.h:22
Definition: analyze-blocking-sizes.cpp:45

References e(), preprocessed_inputfile_t::entries, i, size_triple_t::is_cubic(), size_triple_t::k, log2_pot(), min, and only_cubic_sizes.

Referenced by print_partition().

◆ efficiency_of_partition()

float efficiency_of_partition ( const vector< preprocessed_inputfile_t > &  preprocessed_inputfiles,
const vector< vector< size_t >> &  partition 
)
342  {
343  float efficiency = 1.0f;
344  for (auto s = partition.begin(); s != partition.end(); ++s) {
345  efficiency = min(efficiency, efficiency_of_subset(preprocessed_inputfiles, *s));
346  }
347  return efficiency;
348 }
float efficiency_of_subset(const vector< preprocessed_inputfile_t > &preprocessed_inputfiles, const vector< size_t > &subset)
Definition: analyze-blocking-sizes.cpp:246
RealScalar s
Definition: level1_cplx_impl.h:130

References efficiency_of_subset(), min, and s.

Referenced by print_partition(), and partition_action_t::run().

◆ efficiency_of_subset()

float efficiency_of_subset ( const vector< preprocessed_inputfile_t > &  preprocessed_inputfiles,
const vector< size_t > &  subset 
)
247  {
248  if (subset.size() <= 1) {
249  return 1.0f;
250  }
251  const preprocessed_inputfile_t& first_file = preprocessed_inputfiles[subset[0]];
252  const size_t num_entries = first_file.entries.size();
253  float efficiency = 1.0f;
254  size_t entry_index = 0;
255  size_t first_entry_index_with_this_product_size = 0;
256  uint16_t product_size = first_file.entries[0].product_size;
257  while (entry_index < num_entries) {
258  ++entry_index;
259  if (entry_index == num_entries || first_file.entries[entry_index].product_size != product_size) {
260  float efficiency_this_product_size = 0.0f;
261  for (size_t e = first_entry_index_with_this_product_size; e < entry_index; e++) {
262  float efficiency_this_entry = 1.0f;
263  for (auto i = subset.begin(); i != subset.end(); ++i) {
264  efficiency_this_entry = min(efficiency_this_entry, preprocessed_inputfiles[*i].entries[e].efficiency);
265  }
266  efficiency_this_product_size = max(efficiency_this_product_size, efficiency_this_entry);
267  }
268  efficiency = min(efficiency, efficiency_this_product_size);
269  if (entry_index < num_entries) {
270  first_entry_index_with_this_product_size = entry_index;
271  product_size = first_file.entries[entry_index].product_size;
272  }
273  }
274  }
275 
276  return efficiency;
277 }
#define max(a, b)
Definition: datatypes.h:23

References e(), preprocessed_inputfile_t::entries, i, max, and min.

Referenced by efficiency_of_partition(), find_subset_with_efficiency_higher_than(), and print_partition().

◆ find_partition_with_efficiency_higher_than()

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 
)
472  {
473  out_partition.resize(0);
474 
475  vector<size_t> remainder;
476  for (size_t i = 0; i < preprocessed_inputfiles.size(); i++) {
477  remainder.push_back(i);
478  }
479 
480  while (!remainder.empty()) {
481  vector<size_t> new_subset;
482  find_subset_with_efficiency_higher_than(preprocessed_inputfiles, required_efficiency_to_beat, remainder,
483  new_subset);
484  out_partition.push_back(new_subset);
485  }
486 }
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)
Definition: analyze-blocking-sizes.cpp:405

References find_subset_with_efficiency_higher_than(), and i.

Referenced by partition_action_t::run().

◆ find_subset_with_efficiency_higher_than()

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 
)
407  {
408  out_subset.resize(0);
409 
410  if (required_efficiency_to_beat >= 1.0f) {
411  cerr << "can't beat efficiency 1." << endl;
412  abort();
413  }
414 
415  while (!inout_remainder.empty()) {
416  vector<size_t> candidate_indices(inout_remainder.size());
417  for (size_t i = 0; i < candidate_indices.size(); i++) {
418  candidate_indices[i] = i;
419  }
420 
421  size_t candidate_indices_subset_size = max_feasible_subset_size(candidate_indices.size());
422  while (candidate_indices_subset_size >= 1) {
423  vector<size_t> candidate_indices_subset;
424  make_first_subset(candidate_indices_subset_size, candidate_indices_subset, candidate_indices.size());
425 
426  vector<size_t> best_candidate_indices_subset;
427  float best_efficiency = 0.0f;
428  vector<size_t> trial_subset = out_subset;
429  trial_subset.resize(out_subset.size() + candidate_indices_subset_size);
430  while (true) {
431  for (size_t i = 0; i < candidate_indices_subset_size; i++) {
432  trial_subset[out_subset.size() + i] = inout_remainder[candidate_indices_subset[i]];
433  }
434 
435  float trial_efficiency = efficiency_of_subset(preprocessed_inputfiles, trial_subset);
436  if (trial_efficiency > best_efficiency) {
437  best_efficiency = trial_efficiency;
438  best_candidate_indices_subset = candidate_indices_subset;
439  }
440  if (is_last_subset(candidate_indices_subset, candidate_indices.size())) {
441  break;
442  }
443  next_subset(candidate_indices_subset, candidate_indices.size());
444  }
445 
446  if (best_efficiency > required_efficiency_to_beat) {
447  for (size_t i = 0; i < best_candidate_indices_subset.size(); i++) {
448  candidate_indices[i] = candidate_indices[best_candidate_indices_subset[i]];
449  }
450  candidate_indices.resize(best_candidate_indices_subset.size());
451  }
452  candidate_indices_subset_size--;
453  }
454 
455  size_t candidate_index = candidate_indices[0];
456  auto candidate_iterator = inout_remainder.begin() + candidate_index;
457  vector<size_t> trial_subset = out_subset;
458 
459  trial_subset.push_back(*candidate_iterator);
460  float trial_efficiency = efficiency_of_subset(preprocessed_inputfiles, trial_subset);
461  if (trial_efficiency > required_efficiency_to_beat) {
462  out_subset.push_back(*candidate_iterator);
463  inout_remainder.erase(candidate_iterator);
464  } else {
465  break;
466  }
467  }
468 }
bool is_last_subset(const vector< size_t > &subset, size_t set_size)
Definition: analyze-blocking-sizes.cpp:358
size_t max_feasible_subset_size(size_t n)
Definition: analyze-blocking-sizes.cpp:394
void make_first_subset(size_t subset_size, vector< size_t > &out_subset, size_t set_size)
Definition: analyze-blocking-sizes.cpp:350
void next_subset(vector< size_t > &inout_subset, size_t set_size)
Definition: analyze-blocking-sizes.cpp:360

References efficiency_of_subset(), i, is_last_subset(), make_first_subset(), max_feasible_subset_size(), and next_subset().

Referenced by find_partition_with_efficiency_higher_than().

◆ is_last_subset()

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

Referenced by find_subset_with_efficiency_higher_than(), and next_subset().

◆ is_number_of_subsets_feasible()

bool is_number_of_subsets_feasible ( size_t  n,
size_t  p 
)
381  {
382  assert(n > 0 && p > 0 && p <= n);
383  uint64_t numerator = 1, denominator = 1;
384  for (size_t i = 0; i < p; i++) {
385  numerator *= n - i;
386  denominator *= i + 1;
387  if (numerator > denominator * number_of_subsets_limit) {
388  return false;
389  }
390  }
391  return true;
392 }
#define assert(e,...)
Definition: Logger.h:744
float * p
Definition: Tutorial_Map_using.cpp:9
const size_t number_of_subsets_limit
Definition: analyze-blocking-sizes.cpp:378
std::uint64_t uint64_t
Definition: Meta.h:42

References assert, i, n, number_of_subsets_limit, and p.

Referenced by max_feasible_subset_size().

◆ log2_pot()

uint8_t log2_pot ( size_t  x)
34  {
35  size_t l = 0;
36  while (x >>= 1) l++;
37  return l;
38 }
list x
Definition: plotDoE.py:28

References plotDoE::x.

Referenced by compact_size_triple(), and dump_table_for_subset().

◆ lower_efficiency()

bool lower_efficiency ( const preprocessed_inputfile_entry_t e1,
const preprocessed_inputfile_entry_t e2 
)
169  {
170  return e1.efficiency < e2.efficiency;
171 }
float efficiency
Definition: analyze-blocking-sizes.cpp:166

References preprocessed_inputfile_entry_t::efficiency.

Referenced by evaluate_defaults_action_t::run().

◆ main()

int main ( int argc  ,
char argv[] 
)
707  {
708  cout.precision(default_precision);
709  cerr.precision(default_precision);
710 
711  vector<unique_ptr<action_t>> available_actions;
712  available_actions.emplace_back(new partition_action_t);
713  available_actions.emplace_back(new evaluate_defaults_action_t);
714 
715  vector<string> input_filenames;
716 
717  action_t* action = nullptr;
718 
719  if (argc < 2) {
720  show_usage_and_exit(argc, argv, available_actions);
721  }
722  for (int i = 1; i < argc; i++) {
723  bool arg_handled = false;
724  // Step 1. Try to match action invocation names.
725  for (auto it = available_actions.begin(); it != available_actions.end(); ++it) {
726  if (!strcmp(argv[i], (*it)->invokation_name())) {
727  if (!action) {
728  action = it->get();
729  arg_handled = true;
730  break;
731  } else {
732  cerr << "can't specify more than one action!" << endl;
733  show_usage_and_exit(argc, argv, available_actions);
734  }
735  }
736  }
737  if (arg_handled) {
738  continue;
739  }
740  // Step 2. Try to match option names.
741  if (argv[i][0] == '-') {
742  if (!strcmp(argv[i], "--only-cubic-sizes")) {
743  only_cubic_sizes = true;
744  arg_handled = true;
745  }
746  if (!strcmp(argv[i], "--dump-tables")) {
747  dump_tables = true;
748  arg_handled = true;
749  }
750  if (!arg_handled) {
751  cerr << "Unrecognized option: " << argv[i] << endl;
752  show_usage_and_exit(argc, argv, available_actions);
753  }
754  }
755  if (arg_handled) {
756  continue;
757  }
758  // Step 3. Default to interpreting args as input filenames.
759  input_filenames.emplace_back(argv[i]);
760  }
761 
762  if (dump_tables && only_cubic_sizes) {
763  cerr << "Incompatible options: --only-cubic-sizes and --dump-tables." << endl;
764  show_usage_and_exit(argc, argv, available_actions);
765  }
766 
767  if (!action) {
768  show_usage_and_exit(argc, argv, available_actions);
769  }
770 
771  action->run(input_filenames);
772 }
bool dump_tables
Definition: analyze-blocking-sizes.cpp:32
const int default_precision
Definition: analyze-blocking-sizes.cpp:26
void show_usage_and_exit(int argc, char *argv[], const vector< unique_ptr< action_t >> &available_actions)
Definition: analyze-blocking-sizes.cpp:697
action
Definition: calibrate.py:47
Definition: analyze-blocking-sizes.cpp:506
Definition: analyze-blocking-sizes.cpp:580
Definition: analyze-blocking-sizes.cpp:515

References calibrate::action, default_precision, dump_tables, i, only_cubic_sizes, and show_usage_and_exit().

◆ make_first_subset()

void make_first_subset ( size_t  subset_size,
vector< size_t > &  out_subset,
size_t  set_size 
)
350  {
351  assert(subset_size >= 1 && subset_size <= set_size);
352  out_subset.resize(subset_size);
353  for (size_t i = 0; i < subset_size; i++) {
354  out_subset[i] = i;
355  }
356 }

References assert, and i.

Referenced by find_subset_with_efficiency_higher_than().

◆ max_feasible_subset_size()

size_t max_feasible_subset_size ( size_t  n)
394  {
395  assert(n > 0);
396  const size_t minresult = min<size_t>(n - 1, always_search_subsets_of_size_at_least);
397  for (size_t p = 1; p <= n - 1; p++) {
398  if (!is_number_of_subsets_feasible(n, p + 1)) {
399  return max(p, minresult);
400  }
401  }
402  return n - 1;
403 }
const size_t always_search_subsets_of_size_at_least
Definition: analyze-blocking-sizes.cpp:379
bool is_number_of_subsets_feasible(size_t n, size_t p)
Definition: analyze-blocking-sizes.cpp:381

References always_search_subsets_of_size_at_least, assert, is_number_of_subsets_feasible(), max, n, and p.

Referenced by find_subset_with_efficiency_higher_than().

◆ next_subset()

void next_subset ( vector< size_t > &  inout_subset,
size_t  set_size 
)
360  {
361  if (is_last_subset(inout_subset, set_size)) {
362  cerr << "iterating past the last subset" << endl;
363  abort();
364  }
365  size_t i = 1;
366  while (inout_subset[inout_subset.size() - i] == set_size - i) {
367  i++;
368  assert(i <= inout_subset.size());
369  }
370  size_t first_index_to_change = inout_subset.size() - i;
371  inout_subset[first_index_to_change]++;
372  size_t p = inout_subset[first_index_to_change];
373  for (size_t j = first_index_to_change + 1; j < inout_subset.size(); j++) {
374  inout_subset[j] = ++p;
375  }
376 }
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References assert, i, is_last_subset(), j, and p.

Referenced by find_subset_with_efficiency_higher_than().

◆ operator<<()

ostream& operator<< ( ostream &  s,
const size_triple_t t 
)
58 { return s << "(" << t.k << ", " << t.m << ", " << t.n << ")"; }
t
Definition: plotPSD.py:36

References s, and plotPSD::t.

◆ print_partition()

void print_partition ( const vector< preprocessed_inputfile_t > &  preprocessed_inputfiles,
const vector< vector< size_t >> &  partition 
)
489  {
490  float efficiency = efficiency_of_partition(preprocessed_inputfiles, partition);
491  cout << "Partition into " << partition.size() << " subsets for " << efficiency * 100.0f << "% efficiency" << endl;
492  for (auto subset = partition.begin(); subset != partition.end(); ++subset) {
493  cout << " Subset " << (subset - partition.begin()) << ", efficiency "
494  << efficiency_of_subset(preprocessed_inputfiles, *subset) * 100.0f << "%:" << endl;
495  for (auto file = subset->begin(); file != subset->end(); ++file) {
496  cout << " " << preprocessed_inputfiles[*file].filename << endl;
497  }
498  if (dump_tables) {
499  cout << " Table:" << endl;
500  dump_table_for_subset(preprocessed_inputfiles, *subset);
501  }
502  }
503  cout << endl;
504 }
float efficiency_of_partition(const vector< preprocessed_inputfile_t > &preprocessed_inputfiles, const vector< vector< size_t >> &partition)
Definition: analyze-blocking-sizes.cpp:341
void dump_table_for_subset(const vector< preprocessed_inputfile_t > &preprocessed_inputfiles, const vector< size_t > &subset)
Definition: analyze-blocking-sizes.cpp:279

References dump_table_for_subset(), dump_tables, efficiency_of_partition(), and efficiency_of_subset().

Referenced by partition_action_t::run().

◆ show_usage_and_exit()

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

Referenced by main(), and evaluate_defaults_action_t::run().

Variable Documentation

◆ always_search_subsets_of_size_at_least

const size_t always_search_subsets_of_size_at_least = 2

◆ default_precision

const int default_precision = 4

◆ dump_tables

bool dump_tables = false

Referenced by main(), and print_partition().

◆ number_of_subsets_limit

const size_t number_of_subsets_limit = 100

◆ only_cubic_sizes

bool only_cubic_sizes = false