6. How to debug your models - richoux/GHOST GitHub Wiki

How to debug your models

Debug Macros

Macros GHOST_BENCH and GHOST_TRACE mostly exist to debug GHOST, but can also be used to debug your models.

GHOST_BENCH prints on the standard output statistical details about the run, as well as solver parameters used for the run. There also exist a macro GHOST_DEBUG which is equivalent so far.

GHOST_TRACE prints on the standard output a detailled trace of the solver run, step by step.

Enabling these macros is done with the -D option of your compileur. For instance, to enable the GHOST_BENCH macro, you must write:

$> g++ -o your_program -std=c++20 <list of your cpp files> -lghost -pthread -DGHOST_BENCH

There also exists a macro GHOST_TRACE_PARALLEL while using parallel runs, enabling the trace of the run on each thread and writing it on separated log files.

User-defined candidate prints

Unless you have a good knowledge of how GHOST's solver works, enabling GHOST_BENCH or GHOST_TRACE alone won't be very useful. However, combined with a user-defined prints of candidates and solutions, together with an option to force starting runs from a given candidate, this can help you debugging your models.

Users can write their own class inheriting from ghost::Print and override the method Print::print_candidate to return a std::stringstream object with the desired candidate and solution display.

Once defined, this custom print can be given to the solver through ghost::Options:

  //In the main function
  UserBuilder builder;
  ghost::Solver solver( builder );
  
  std::shared_ptr<Print> my_printer = make_shared<UserPrint>();

  ghost::Options options;
  options.print = my_printer;
  
  double cost;
  std::vector<int> solution;
  
  solver.fast_search( cost, solution, 10s, options );
}

This can be particularly powerful while combined with starting the search from a custom starting candidate, or even directly from a solution you know. To do so, simply set the value of your variables into your user-defined ModelBuilder while declaring your variables, and tells the solver to start searching from this candidate instead of picking up one randomly.

  //In your ModelBuilder class
  void UserBuilder::declare_variables()
  {
    ...
	//set the initial value of your variables after declaring them
	variables[0]->set_value( 5 );
	variables[1]->set_value( 42 );
	variables[2]->set_value( 13 );
	...
  }
  //In the main function
  ...
  options.custom_starting_point = true
  ...
}
⚠️ **GitHub.com Fallback** ⚠️