=== DiVinE's automatic instantiate readme for DiVinE developers ===

You may know that instantiation of algorithms was always pain, and that divine
required lot of memory for compilation. Hopefully this system solves it once and
for all.

All instantiation files are located in divine/instances, therefore all paths
are relative to this prefix. Also all types are expected to be defined
under divine::instantiate namespace.

== How it works ==

Instances are symbolically defined in definitions.h and then generated
at compile time to N files which can be separately compiled. N can be set
by CMake varibale INSTANCE_FILES_CNT, more you set less memory will be required
for build, for release with all components enabled reasonable (and default)
value is 32. You may want to use more if you have little memory or want
heavily parallel builds but compilations slows down (see bottom for benchmark).

== Components ==

definitions.h

  - the core of instantiation and hopefully only file you will need to edit
    when adding new algorithm/generator/whatever...

  * SYMBOLIC COMPONENTS
  - symbolic objects representing each possible component are defined here
    using preprocessor macros to save on code
  - each symbolic objects represents component (all listed functions are static,
    all listed fields are static constexpr), and contains following items
    - [mandatory] typedef allowing reflection of type of component
      (IsAlgorithm, IsStore,...)
    - [mandatory] symbol -- textual representation of using declaration
      of component
    - [mandatory] key -- textual representation of structure name
    - [mandatory] SupportedBy specification
    - [mandatory] bool select( Meta & ) -- function for run-time selection
    - [optional] header -- colon (':') separated list of headers implementing
      component
    - [optional] name
    - [optional] void postSelect( Meta & ) -- is run immediately after component
      is selected
    - [optional] void init( Meta & ) -- is run after all components are selected
  - those objects are defined by preprocessor macros which allows setting common
    differentiating factors of given type of component
  - each type of component (algorithm, store, ...) is enclosed is namespace
  - if component is not available due to configuration options, typedef for
    _Missing must be provided
  - for each type of component is defined list of all (possibly) available
    components (algorithm::Algorithms, store::Stores), components are tested
    for selection in order, last is considered default
  - if no default component is possible, as for algorithm or generator,
    special default derived from InstantiationError is provided, implementing
    function static std::string instantiationError( Meta & )
  - macros can be used even in case where you need to implement additional
    function -- use inheritance -- see generators::LLVM for example

  * INSTANTIATION ORDER
  - order of instantiation is given by type Instantiation, which is using
    for TypeList of component types (actually of lists of components)
  
  * DEPENDENCIES
  - components may have dependecies on other comonents, but only on those
    selected before
  - is is given by using SupportedBy = ... which can be set either to Any,
    symbolic representation of one component, or boolean combination of
    components such as
    And< generator::Dve, Or< algorithm::NestedDfs, algorithm::Map > >
    meaning that component can be selected only if generator is Dve, and
    algorithm is either NestedDfs or Map
  - if specified in macro you will need to use typedef to give name to
    your constraint if it uses comma (',')
  - combination which does not satisfy dependencies will not be generated


IT SHOULD NOT BE NECESSARY TO EDIT FOLLOWING FILES TO ADD NEW COMPONENT

select.h

  - public interface to instantiation, only header which should be included
    outside of divine/instances
  - defines std::unique_ptr< ::divine::algorithm::Algorithm > select( Meta & )


select-impl.h

  - low level template magic which invokes instantiation

select.cpp

  - implements select.h

create.h

  - declaration of internal structures for which specializations are generated

generator/generator.cpp

  - generator of instance specializations
  - is built and invoked when building divine, before building
    libdivine-instances
  - generates files in BUILD_ROOT/divine/instances/auto

BUILD_ROOT/divine/instances/auto/extern.h

  - declaration of all specialization structures and functions together
    with extern template declarations to disallow implicit instantiation

BUILD_ROOT/divine/instances/auto/instance-#.cpp

  - code generating instances

== Benchmark ==

measurements with release enables, and following configuration:
POSIX COIN PERFORMANCE DVE COMPRESSION COMPACT POOLS COMPACT_CELL TIMED LLVM MPI

8 Instance files, -j1
peak 5999168 KB
real 2708.56
user 2579.52
sys 80.18

16 Instance files, -j1
peak 3343764 KB
real 2400.44
user 2291.16
sys 82.56

32 Instance files, -j1
peak 2048528 KB
real 2558.32
user 2462.01
sys 63.90

64 Instance files, -j1
peak 1641568 KB
real 3003.56
user 2877.14
sys 94.13

64 Instance files, -j2
peak 1641572 KB
real 1601.55
user 3048.26
sys 62.67

64 Instance files, -j4
peak 1641568 KB
real 1386.93
user 5109.66
sys 95.75
