Parallel solving in Z3

前端 未结 2 638
失恋的感觉
失恋的感觉 2021-01-13 14:55

One of the new features in Z3 4.8.1 is parallel solving:

A parallel mode is available for select theories, including QF_BV. By setting parallel.enab

2条回答
  •  我在风中等你
    2021-01-13 15:20

    Short answer: As @LeventErkok points out, the syntax of parallel.enable=true is for use in the command line to the z3 executable itself. And as he says and @Claies's link had indicated, if you are using a binding, you will want to use the relevant set_param() method. For C++ that is set_param("parallel.enable", true);

    When I added this to the C++ binding example, it gave basically the same output...though it spat out some extra information to stderr, a bunch of lines like:

    (tactic.parallel :progress 0% :closed 0 :open 1)
    (tactic.parallel :progress 100% :status sat :closed 0 :open 0)
    

    Which matches @LeventErkrok's observed difference using the z3 tool on another problem.


    It mentions that just parallel.enable=true needs to be set but I can't find that parallel structure in the code.

    (I was curious what Z3 was all about, so I also went looking in the C++ sources for parallel.enable. So that's where my answer started out from, before people who knew more answered. My findings left here for anyone interested...)

    Long answer: If you're looking through the sources for z3 itself, you won't find a C++ object called parallel where you'd write parallel.enable = true;. It's a property stored in a configuration object managed by string names. That configuration object is called parallel_params, it's not in GitHub because it is generated as part of the build process, into src/solver/parallel_params.hpp

    The specification for these properties and their defaults is per-module in a .pyg file. This is just Python which is loaded by the build preparation process and eval()'d with a few things defined. The parallel solver options are in src/solver/parallel_params.pyg, e.g.:

    def_module_params('parallel',
        description='parameters for parallel solver',
        class_name='parallel_params',
        export=True,
        params=(
            ('enable', BOOL, False, 'enable parallel solver ...'),
            ('threads.max', UINT, 10000, 'caps maximal number of threads ...'),
            # ...etc.
    

    If you want to change these defaults while building z3, it looks like you have to edit the .pyg file, as there seems no parameterization for something like python scripts/mk_make.py parallel.enable=true.

    As an example of how changing this file affects the generated header defining the parallel properties, I directly modified parallel_params.pyg to say "True" instead of "False" for its default. The consequence was the following 2-line diff to the generated src/solver/parallel_params.hpp file:

    -- a/src/solver/parallel_params.hpp
    +++ b/src/solver/parallel_params.hpp
    @@ -9,7 +9,7 @@ struct parallel_params {
       parallel_params(params_ref const & _p = params_ref::get_empty()):
          p(_p), g(gparams::get_module("parallel")) {}
       static void collect_param_descrs(param_descrs & d) {
    -    d.insert("enable", CPK_BOOL, "enable parallel solver by default on selected tactics (for QF_BV)", "false","parallel");
    +    d.insert("enable", CPK_BOOL, "enable parallel solver by default on selected tactics (for QF_BV)", "true","parallel");
         d.insert("threads.max", CPK_UINT, "caps maximal number of threads below the number of processors", "10000","parallel");
         d.insert("conquer.batch_size", CPK_UINT, "number of cubes to batch together for fast conquer", "100","parallel");
         d.insert("conquer.restart.max", CPK_UINT, "maximal number of restarts during conquer phase", "5","parallel");
    @@ -23,7 +23,7 @@ struct parallel_params {
          REG_MODULE_PARAMS('parallel', 'parallel_params::collect_param_descrs')
          REG_MODULE_DESCRIPTION('parallel', 'parameters for parallel solver')
       */
    -  bool enable() const { return p.get_bool("enable", g, false); }
    +  bool enable() const { return p.get_bool("enable", g, true); }
       unsigned threads_max() const { return p.get_uint("threads.max", g, 10000u); }
       unsigned conquer_batch_size() const { return p.get_uint("conquer.batch_size", g, 100u); }
       unsigned conquer_restart_max() const { return p.get_uint("conquer.restart.max", g, 5u); }
    

提交回复
热议问题