Fleet  0.0.9
Inference in the LOT
Fleet.h
Go to the documentation of this file.
1 
361 #pragma once
362 
363 #include <filesystem>
364 #include <sys/resource.h> // just for setting priority defaulty
365 #include <unistd.h>
366 #include <stdlib.h>
367 #include <csignal>
368 #include <string>
369 
370 // For macs:
371 #ifdef __APPLE__
372  #include <sys/syslimits.h> // used to get PATH_MAX
373  #include <mach-o/dyld.h> // dynamic link editor with method to get executable path
374 #endif
375 
376 
377 const std::string FLEET_VERSION = "0.1.4";
378 
379 #include "Random.h"
380 #include "Timing.h"
381 #include "Control.h"
382 
386 
387 #include "FleetArgs.h"
388 
389 unsigned long random_seed = 0;
390 
391 // This is global that checks whether CTRL_C has been pressed
392 // NOTE: this must be registered in main with signal(SIGINT, Fleet::fleet_interrupt_handler);
393 //volatile sig_atomic_t CTRL_C = false;
394 std::atomic<bool> CTRL_C = false;
395 
396 // apparently some OSes don't define this
397 #ifndef HOST_NAME_MAX
398  const size_t HOST_NAME_MAX = 256;
399 #endif
400 char hostname[HOST_NAME_MAX];
401 
402 // store the main thread id if we want it
403 std::thread::id main_thread_id = std::this_thread::get_id();
404 
405 #include "FleetStatistics.h"
406 
416 class Fleet {
417 public:
418  CLI::App app;
419  timept start_time;
420  bool done; // if this is true, we don't call completed on destruction
421 
422  Fleet(std::string brief) : app{brief}, done(false) {
423 
424  app.add_option("-S,--seed", random_seed, "Seed the rng (0 is no seed)");
425  app.add_option("-s,--steps", FleetArgs::steps, "Number of MCMC or MCTS search steps to run");
426  app.add_option("--inner-steps", FleetArgs::inner_steps, "Steps to run inner loop of a search");
427  app.add_option("--burn", FleetArgs::burn, "Burn this many steps");
428  app.add_option("--thin", FleetArgs::thin, "Thinning on callbacks");
429  app.add_option("-p,--print", FleetArgs::print, "Print out every this many");
430  app.add_option("-t,--top", FleetArgs::ntop, "The number to store");
431  app.add_option("-n,--threads", FleetArgs::nthreads, "Number of threads for parallel search");
432  app.add_option("--explore", FleetArgs::explore, "Exploration parameter for MCTS");
433  app.add_option("--restart", FleetArgs::restart, "If we don't improve after this many, restart a chain");
434  app.add_option("-c,--chains", FleetArgs::nchains, "How many chains to run");
435  app.add_option("--ct", FleetArgs::chainsthreads, "Specify chains and threads at the same time");
436 
437  app.add_option("--partition-depth", FleetArgs::partition_depth, "How deep do we recurse when we do partition-mcmc?");
438 
439  app.add_option("-o,--output", FleetArgs::output_path, "Where we write output");
440  app.add_option("--input", FleetArgs::input_path, "Read standard input from here");
441  app.add_option("-T,--time", FleetArgs::timestring, "Stop (via CTRL-C) after this much time (takes smhd as seconds/minutes/hour/day units)");
442  app.add_option("--inner-restart", FleetArgs::inner_restart, "Inner restart");
443  app.add_option("--inner-time", FleetArgs::inner_timestring, "Inner time");
444  app.add_option("--inner-thin", FleetArgs::inner_thin, "Inner thinning");
445  app.add_option("--tree", FleetArgs::tree_path, "Write the tree here");
446 
447  app.add_option("--omp-threads", FleetArgs::omp_threads, "How many threads to run with OMP");
448 
449  app.add_option("--header", FleetArgs::print_header, "Set to 0 to not print header");
450 
451  app.add_flag("--top-print-best", FleetArgs::top_print_best, "Should all tops defaultly print their best?");
452  app.add_flag("--print-proposals", FleetArgs::print_proposals, "Should we print out proposals?");
453 
454 // app.add_flag( "-q,--quiet", quiet, "Don't print very much and do so on one line");
455 // app.add_flag( "-C,--checkpoint", checkpoint, "Checkpoint every this many steps");
456 
457  start_time = now();
458 
459  // now if we are running MPI
460 // #ifdef FLEET_MPI
461 
462 // #endif
463 
464  }
465 
469  virtual ~Fleet() {
470  if(not done) completed();
471  }
472 
476 
477 
478  static void fleet_interrupt_handler(int signum) {
479  if(signum == SIGINT) {
480  CTRL_C = true;
481  }
482  else if(signum == SIGHUP) {
483  // do nothing -- defaultly Fleet mutes SIGHUP so that commands left in the terminal will continue
484  // this is so that if we get disconnected on a terminal run, the job is maintained
485  }
486  }
487 
488 
489  template<typename T>
490  void add_option(std::string c, T& var, std::string description ) {
491  app.add_option(c, var, description);
492  }
493  template<typename T>
494  void add_flag(std::string c, T& var, std::string description ) {
495  app.add_flag(c, var, description);
496  }
497 
498  int initialize(int argc, char** argv) {
499 
500  //CLI11_PARSE(app, argc, argv);
501  app.parse(argc, argv); // parse here -- and DO NOT catch exit codes (unlike the macro above)
502  // if we catch exit codes, we silently keep running without parsing...
503 
504  // set our own handlers -- defaulty HUP won't stop
505  std::signal(SIGINT, Fleet::fleet_interrupt_handler);
506  std::signal(SIGHUP, Fleet::fleet_interrupt_handler);
507 
508  // give us a defaultly kinda nice niceness
509  setpriority(PRIO_PROCESS, 0, 5);
510 
511  // convert everything to ms
514 
515 
516  //
517  if( FleetArgs::chainsthreads != 0) {
518  assert((FleetArgs::nchains == 1 and FleetArgs::nthreads==1) && "*** Cannot specify chains or threads with --ct");
521  }
522 
523  // seed the rng
524  DefaultRNG.seed(random_seed);
525 
527  // Print standard fleet header
528  gethostname(hostname, HOST_NAME_MAX);
529 
530  #ifdef __APPLE__
531  char path[PATH_MAX+1];
532  uint32_t size = sizeof(path);
533  _NSGetExecutablePath(path, &size);
534  char tmp[128]; sprintf(tmp, "md5sum %s", path);
535  #else
536 
537  // and build the command to get the md5 checksum of myself
538  char tmp[128]; sprintf(tmp, "md5sum /proc/%d/exe", getpid());
539  #endif
540 
541  std::filesystem::path cwd = std::filesystem::current_path();
542  std::string exc = system_exec(tmp); exc.erase(exc.length()-1); // came with a newline?
543 
544  print("# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
545  print("# Running Fleet on " + std::string(hostname) + " with PID=" + str(getpid()) + " by user " + getenv("USER") + " at " + datestring());
546  print("# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
547  print("# Fleet version: ", FLEET_VERSION);
548  print("# Executable checksum: ", exc);
549  print("# Path:", cwd.string() );
550  print("# Run options: ");
551  for(int a=0;a<argc;a++) {
552  print("#\t", argv[a]);
553  }
554  print("# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
555 
556  }
557 
558  // give warning for infinite runs:
559  if(FleetArgs::steps == 0 and FleetArgs::runtime==0) {
560  CERR "# Warning: you haven not specified --time or --steps so this will run forever or until CTRL-C." ENDL;
561  }
562 
563  return 0;
564  }
565 
566 
567  void completed() {
568 
570  auto elapsed_seconds = time_since(start_time) / 1000.0;
571 
572  COUT "# Elapsed time:" TAB elapsed_seconds << " seconds " ENDL;
574  COUT "# Samples per second:" TAB FleetStatistics::global_sample_count/elapsed_seconds ENDL;
575  COUT "# Global sample count:" TAB FleetStatistics::global_sample_count ENDL;
576  }
578  COUT "# Total Beam Search steps:" TAB FleetStatistics::beam_steps ENDL;
579  }
581  COUT "# Total enumeration steps:" TAB FleetStatistics::enumeration_steps ENDL;
582  }
584  COUT "# Warning: " TAB FleetStatistics::depth_exceptions TAB " grammar depth exceptions." ENDL;
585  }
586 
587  COUT "# Total posterior calls:" TAB FleetStatistics::posterior_calls ENDL;
588  COUT "# Millions of VM ops per second:" TAB (FleetStatistics::vm_ops/1000000)/elapsed_seconds ENDL;
589 
590  COUT "# Fleet completed at " << datestring() ENDL;
591 
592  }
593 
594  // setting this makes sure we won't call it again
595  done = true;
596 
597  // HMM CANT DO THIS BC THERE MAY BE MORE THAN ONE TREE....
598  //COUT "# MCTS tree size:" TAB m.size() ENDL;
599  //COUT "# Max score: " TAB maxscore ENDL;
600  //COUT "# MCTS steps per second:" TAB m.statistics.N ENDL;
601  }
602 
603 };
604 
unsigned long burn
Definition: FleetArgs.h:14
int omp_threads
Definition: FleetArgs.h:43
unsigned long inner_runtime
Definition: FleetArgs.h:26
unsigned long print
Definition: FleetArgs.h:34
std::atomic< uintmax_t > global_sample_count(0)
std::string tree_path
Definition: FleetArgs.h:40
unsigned long inner_thin
Definition: FleetArgs.h:28
#define TAB
Definition: IO.h:19
std::atomic< uintmax_t > depth_exceptions(0)
double explore
Definition: FleetArgs.h:19
bool print_proposals
Definition: FleetArgs.h:36
Rng DefaultRNG
std::string system_exec(const char *cmd)
Definition: Miscellaneous.h:11
size_t chainsthreads
Definition: FleetArgs.h:22
const std::string FLEET_VERSION
Definition: Fleet.h:377
unsigned long ntop
Definition: FleetArgs.h:15
std::atomic< uintmax_t > enumeration_steps(0)
std::string inner_timestring
Definition: FleetArgs.h:30
std::string str(BindingTree *t)
Definition: BindingTree.h:195
std::string timestring
Definition: FleetArgs.h:29
volatile sig_atomic_t CTRL_C
size_t partition_depth
Definition: FleetArgs.h:23
void print(FIRST f, ARGS... args)
Lock output_lock and print to std:cout.
Definition: IO.h:53
int print_header
Definition: FleetArgs.h:17
std::atomic< uintmax_t > posterior_calls(0)
std::atomic< uintmax_t > vm_ops(0)
unsigned long inner_restart
Definition: FleetArgs.h:27
#define CERR
Definition: IO.h:23
std::atomic< uintmax_t > beam_steps(0)
size_t nchains
Definition: FleetArgs.h:21
#define ENDL
Definition: IO.h:21
void seed(unsigned long s)
Seed only if s is nonzero.
Definition: Rng.h:60
This is a thread_local rng whose first object is used to see others (in other threads). This way, we can have thread_local rngs that all are seeded deterministcally in Fleet via –seed=X.
std::string output_path
Definition: FleetArgs.h:41
std::string input_path
Definition: FleetArgs.h:39
unsigned long inner_steps
Definition: FleetArgs.h:13
bool top_print_best
Definition: FleetArgs.h:37
size_t nthreads
Definition: FleetArgs.h:20
unsigned long runtime
Definition: FleetArgs.h:25
#define COUT
Definition: IO.h:24
unsigned long steps
Definition: FleetArgs.h:12
time_t convert_time(const std::string &s)
Give a timepoint for the current time.
Definition: Timing.h:79
unsigned long restart
Definition: FleetArgs.h:32
This class has all the information for running MCMC or MCTS in a little package. It defaultly constru...
unsigned long thin
Definition: FleetArgs.h:33