From dcc19e9425659882b44eed68c9a3241b6f700204 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Wed, 2 Oct 2019 10:25:16 +0200 Subject: [PATCH 01/35] Try removing the ipyparallel client caching mechanism. --- pygmo/_py_islands.py | 53 ++++++-------------------------------------- 1 file changed, 7 insertions(+), 46 deletions(-) diff --git a/pygmo/_py_islands.py b/pygmo/_py_islands.py index 6e7f15919..16e4d68bb 100644 --- a/pygmo/_py_islands.py +++ b/pygmo/_py_islands.py @@ -449,28 +449,6 @@ def shutdown_pool(): mp_island._pool_size = None -# NOTE: the idea here is that we don't want to create a new client for -# every island: creation is expensive, and we cannot have too many clients -# as after a certain threshold ipyparallel starts erroring out. -# So we store the clients as values in a dict whose keys are the arguments -# passed to Client() upon construction, and we re-use existing clients -# if the construction arguments are identical. -# NOTE: this is not a proper cache as it never kicks anything out, but as -# a temporary solution it is fine. Consider using something like a LRU -# cache in the future. -_client_cache = {} -_client_cache_lock = _Lock() - - -def _hashable(v): - # Determine whether v can be hashed. - try: - hash(v) - except TypeError: - return False - return True - - class ipyparallel_island(object): """Ipyparallel island. @@ -492,32 +470,15 @@ def __init__(self, *args, **kwargs): def _init(self, *args, **kwargs): # A small helper function which will do the following: - # * get a client from the cache in a thread safe manner, or - # create a new one from scratch - # * store the input arguments as class members - # * create a LoadBalancedView from the client - # * create a lock to regulate access to the view + # * create a new client from scratch, + # * store the input arguments as class members, + # * create a LoadBalancedView from the client, + # * create a lock to regulate access to the view, # * return the view. from ipyparallel import Client - # Turn the arguments into something that might be hashable. - # Make sure the kwargs are sorted so that two sets of identical - # kwargs will be recognized as equal also if the keys are stored - # in different order. - args_key = (args, tuple(sorted([(k, kwargs[k]) for k in kwargs]))) - if _hashable(args_key): - with _client_cache_lock: - # Try to see if a client constructed with the same - # arguments already exists in the cache. - rc = _client_cache.get(args_key) - if rc is None: - # No cached client exists. Create a new client - # and store it in the cache. - rc = Client(*args, **kwargs) - _client_cache[args_key] = rc - else: - # If the arguments are not hashable, just create a brand new - # client. - rc = Client(*args, **kwargs) + + # Create the client. + rc = Client(*args, **kwargs) # Save the init arguments. self._args = args From eb634e1eff77964b97835fb6c7de779805b6dcf4 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Wed, 2 Oct 2019 13:22:56 +0200 Subject: [PATCH 02/35] Try raising ulimit -n. --- tools/install_travis.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/install_travis.sh b/tools/install_travis.sh index 29afd5595..ce9fcdaac 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -6,6 +6,9 @@ set -x # Exit on error. set -e +ulimit -n +ulimit -n 10000 + if [[ "${PAGMO_BUILD}" != manylinux* ]]; then export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" From 36c04730ac1e80434a1436e90f65683aef3289a7 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Wed, 2 Oct 2019 13:42:47 +0200 Subject: [PATCH 03/35] Forgot the dll version bump in the previous pr. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2c21bb5b..34c53fe58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,8 +283,8 @@ if(PAGMO_BUILD_PAGMO) # Setup of the pagmo library. add_library(pagmo SHARED "${PAGMO_SRC_FILES}") - set_property(TARGET pagmo PROPERTY VERSION "1.0") - set_property(TARGET pagmo PROPERTY SOVERSION 1) + set_property(TARGET pagmo PROPERTY VERSION "2.0") + set_property(TARGET pagmo PROPERTY SOVERSION 2) target_compile_options(pagmo PRIVATE "$<$:${PAGMO_CXX_FLAGS_DEBUG}>" "$<$:${PAGMO_CXX_FLAGS_RELEASE}>") set_target_properties(pagmo PROPERTIES CXX_VISIBILITY_PRESET hidden) set_target_properties(pagmo PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE) From 7f77d0574611204c3ddc7124616e08699ad843a1 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Wed, 2 Oct 2019 13:43:02 +0200 Subject: [PATCH 04/35] Try raising ulimit more on travis. [skip appveyor] --- tools/install_travis.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/install_travis.sh b/tools/install_travis.sh index ce9fcdaac..b6bfa62b2 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -7,7 +7,8 @@ set -x set -e ulimit -n -ulimit -n 10000 +ulimit -n 60000 +ulimit -n if [[ "${PAGMO_BUILD}" != manylinux* ]]; then export deps_dir=$HOME/local From 298ad9590ea4f0ed6e507b0f0ee57882d2bdbdf7 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 00:32:16 +0100 Subject: [PATCH 05/35] Evovling the implementation. --- pygmo/_py_islands.py | 14 ++++++++------ tools/install_travis.sh | 4 ---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pygmo/_py_islands.py b/pygmo/_py_islands.py index 16e4d68bb..02d7e6bfd 100644 --- a/pygmo/_py_islands.py +++ b/pygmo/_py_islands.py @@ -471,19 +471,20 @@ def __init__(self, *args, **kwargs): def _init(self, *args, **kwargs): # A small helper function which will do the following: # * create a new client from scratch, - # * store the input arguments as class members, + # * store a copy of the input arguments as class members, # * create a LoadBalancedView from the client, # * create a lock to regulate access to the view, # * return the view. from ipyparallel import Client + from copy import deepcopy + + # Save the init arguments. + self._args = deepcopy(args) + self._kwargs = deepcopy(kwargs) # Create the client. rc = Client(*args, **kwargs) - # Save the init arguments. - self._args = args - self._kwargs = kwargs - # NOTE: we need to regulate access to the view because, # while run_evolve() is running in a separate thread, we # could be doing other things involving the view (e.g., @@ -504,7 +505,8 @@ def __getstate__(self): # For pickle/unpickle, we employ the construction # arguments, which will be used to re-init the class # during unpickle. - return self._args, self._kwargs + from copy import deepcopy + return deepcopy(self._args), deepcopy(self._kwargs) def __setstate__(self, state): self._lview = self._init(*state[0], **state[1]) diff --git a/tools/install_travis.sh b/tools/install_travis.sh index b6bfa62b2..29afd5595 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -6,10 +6,6 @@ set -x # Exit on error. set -e -ulimit -n -ulimit -n 60000 -ulimit -n - if [[ "${PAGMO_BUILD}" != manylinux* ]]; then export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" From f8a665a563206bd2da7a14296ee4324f0b95b565 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 00:41:12 +0100 Subject: [PATCH 06/35] Try adding a conda-based py38 build. --- .circleci/config.yml | 9 ++++++ tools/circleci_bionic_gcc7_conda_py38.sh | 41 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tools/circleci_bionic_gcc7_conda_py38.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index b838aee59..993fe3458 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,14 @@ version: 2 jobs: + bionic_gcc7_conda_py38: + docker: + - image: circleci/buildpack-deps:bionic + steps: + - checkout + - run: + name: Build and test + command: bash ./tools/circleci_bionic_gcc7_conda_py38.sh bionic_gcc7_coverage: docker: - image: circleci/buildpack-deps:bionic @@ -38,6 +46,7 @@ workflows: version: 2 all_builds: jobs: + - bionic_gcc7_conda_py38 - bionic_gcc7_coverage - cosmic_gcc8_asan - cosmic_clang7 diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh new file mode 100644 index 000000000..71665777a --- /dev/null +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Echo each command +set -x + +# Exit on error. +set -e + +# Core deps. +sudo apt-get install build-essential wget + +# Install conda+deps. +wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh +export deps_dir=$HOME/local +export PATH="$HOME/miniconda/bin:$PATH" +export PATH="$deps_dir/bin:$PATH" +bash miniconda.sh -b -p $HOME/miniconda +conda config --add channels conda-forge --force +conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.8 numpy cloudpickle dill ipyparallel numba pip" +conda create -q -p $deps_dir -y +source activate $deps_dir + +# Build/install pagmo. +mkdir build +cd build +cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_TESTS=no -DPAGMO_WITH_EIGEN3=yes -DPAGMO_WITH_NLOPT=yes -DPAGMO_WITH_IPOPT=yes +make -j2 VERBOSE=1 install + +# Build/install pygmo. +cd .. +mkdir build_py +cd build_py +cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_PAGMO=no -DPAGMO_BUILD_PYGMO=yes +make -j2 VERBOSE=1 install + +# Run the tests. +cd / +python -c "import pygmo; pygmo.test.run_test_suite(1)"; + +set +e +set +x From 9428f8b7cb55a89aa278ea4234022cd5f3a21ab0 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 00:45:41 +0100 Subject: [PATCH 07/35] Debug. --- .circleci/config.yml | 9 ++++----- tools/circleci_bionic_gcc7_conda_py38.sh | 1 + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 993fe3458..dd77785c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,8 +47,7 @@ workflows: all_builds: jobs: - bionic_gcc7_conda_py38 - - bionic_gcc7_coverage - - cosmic_gcc8_asan - - cosmic_clang7 - - bionic_clang6_release - \ No newline at end of file + # - bionic_gcc7_coverage + # - cosmic_gcc8_asan + # - cosmic_clang7 + # - bionic_clang6_release diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index 71665777a..3cb056805 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -19,6 +19,7 @@ conda config --add channels conda-forge --force conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.8 numpy cloudpickle dill ipyparallel numba pip" conda create -q -p $deps_dir -y source activate $deps_dir +conda install $conda_pkgs -y # Build/install pagmo. mkdir build From 6cb5d4c122c0c9ab8338a632bb19960025a851b3 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 00:52:48 +0100 Subject: [PATCH 08/35] WIP. --- tools/circleci_bionic_gcc7_conda_py38.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index 3cb056805..aa0f2f602 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -24,16 +24,21 @@ conda install $conda_pkgs -y # Build/install pagmo. mkdir build cd build -cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_TESTS=no -DPAGMO_WITH_EIGEN3=yes -DPAGMO_WITH_NLOPT=yes -DPAGMO_WITH_IPOPT=yes +cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_TESTS=no -DPAGMO_WITH_EIGEN3=yes -DPAGMO_WITH_NLOPT=yes -DPAGMO_WITH_IPOPT=yes -DBoost_NO_BOOST_CMAKE=ON make -j2 VERBOSE=1 install # Build/install pygmo. cd .. mkdir build_py cd build_py -cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_PAGMO=no -DPAGMO_BUILD_PYGMO=yes +cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_PAGMO=no -DPAGMO_BUILD_PYGMO=yes -DBoost_NO_BOOST_CMAKE=ON make -j2 VERBOSE=1 install +# Start ipcluster. +ipcluster start --daemonize=True; +# Give some time for the cluster to start up. +sleep 20; + # Run the tests. cd / python -c "import pygmo; pygmo.test.run_test_suite(1)"; From 485d29ea68db029d7263920da247046b17db8e15 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 01:05:47 +0100 Subject: [PATCH 09/35] More tentative WIP. --- pygmo/_py_islands.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pygmo/_py_islands.py b/pygmo/_py_islands.py index 02d7e6bfd..b0e1fcada 100644 --- a/pygmo/_py_islands.py +++ b/pygmo/_py_islands.py @@ -71,11 +71,13 @@ def _evolve_func_mp_pipe(conn, ser_algo_pop): conn.close() -def _evolve_func_ipy(algo, pop): +def _evolve_func_ipy(ser_algo_pop): # The evolve function that is actually run from the separate processes # in ipyparallel_island. + import pickle + algo, pop = pickle.loads(ser_algo_pop) new_pop = algo.evolve(pop) - return algo, new_pop + return pickle.dumps((algo, new_pop)) class mp_island(object): @@ -535,9 +537,11 @@ def run_evolve(self, algo, pop): """ + import pickle + ser_algo_pop = pickle.dumps((algo, pop)) with self._view_lock: - ret = self._lview.apply_async(_evolve_func_ipy, algo, pop) - return ret.get() + ret = self._lview.apply_async(_evolve_func_ipy, ser_algo_pop) + return pickle.loads(ret.get()) def get_name(self): """Island's name. From bd07cf190e31b3053b9c611b9f76ded48a1d8695 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 01:22:23 +0100 Subject: [PATCH 10/35] Disable ipyparallel for now. --- tools/circleci_bionic_gcc7_conda_py38.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index aa0f2f602..c8638bbd4 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -16,7 +16,7 @@ export PATH="$HOME/miniconda/bin:$PATH" export PATH="$deps_dir/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.8 numpy cloudpickle dill ipyparallel numba pip" +conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.8 numpy cloudpickle dill numba pip" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y @@ -34,11 +34,6 @@ cd build_py cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_PAGMO=no -DPAGMO_BUILD_PYGMO=yes -DBoost_NO_BOOST_CMAKE=ON make -j2 VERBOSE=1 install -# Start ipcluster. -ipcluster start --daemonize=True; -# Give some time for the cluster to start up. -sleep 20; - # Run the tests. cd / python -c "import pygmo; pygmo.test.run_test_suite(1)"; From 2a500e5670995f750bcc8eb0e88f4cc6d85527f3 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 01:58:44 +0100 Subject: [PATCH 11/35] Try 3.7. --- tools/circleci_bionic_gcc7_conda_py38.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index c8638bbd4..89bae5a4a 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -16,7 +16,7 @@ export PATH="$HOME/miniconda/bin:$PATH" export PATH="$deps_dir/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.8 numpy cloudpickle dill numba pip" +conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.7 numpy cloudpickle dill numba pip" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y From 6acd21276cdcec43628eabc1abae391e7ef98152 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 02:21:39 +0100 Subject: [PATCH 12/35] Debug. --- tools/circleci_bionic_gcc7_conda_py38.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index 89bae5a4a..b6359fe89 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -16,7 +16,7 @@ export PATH="$HOME/miniconda/bin:$PATH" export PATH="$deps_dir/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda config --add channels conda-forge --force -conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.7 numpy cloudpickle dill numba pip" +conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=3.8 numpy cloudpickle dill numba pip" conda create -q -p $deps_dir -y source activate $deps_dir conda install $conda_pkgs -y @@ -38,5 +38,14 @@ make -j2 VERBOSE=1 install cd / python -c "import pygmo; pygmo.test.run_test_suite(1)"; +echo "DONE" +echo "DONE" +echo "DONE" +echo "DONE" +echo "DONE" +echo "DONE" +echo "DONE" +ps aux + set +e set +x From d046e0d8455ae493e105bfcb65247b53014e400d Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 14:46:07 +0100 Subject: [PATCH 13/35] Workaround for py38 bug. --- tools/circleci_bionic_gcc7_conda_py38.sh | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index b6359fe89..2131b5ac7 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -36,16 +36,7 @@ make -j2 VERBOSE=1 install # Run the tests. cd / -python -c "import pygmo; pygmo.test.run_test_suite(1)"; - -echo "DONE" -echo "DONE" -echo "DONE" -echo "DONE" -echo "DONE" -echo "DONE" -echo "DONE" -ps aux +python -c "import pygmo; pygmo.test.run_test_suite(1); pygmo.mp_island.shutdown_pool()"; set +e set +x From 914694e67b51b7af98e41ce98b21feeff2b8d372 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 17:43:30 +0100 Subject: [PATCH 14/35] Small tweaks. [skip ci] --- pygmo/_py_islands.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/pygmo/_py_islands.py b/pygmo/_py_islands.py index b0e1fcada..0342d54bc 100644 --- a/pygmo/_py_islands.py +++ b/pygmo/_py_islands.py @@ -71,15 +71,6 @@ def _evolve_func_mp_pipe(conn, ser_algo_pop): conn.close() -def _evolve_func_ipy(ser_algo_pop): - # The evolve function that is actually run from the separate processes - # in ipyparallel_island. - import pickle - algo, pop = pickle.loads(ser_algo_pop) - new_pop = algo.evolve(pop) - return pickle.dumps((algo, new_pop)) - - class mp_island(object): """Multiprocessing island. @@ -451,6 +442,15 @@ def shutdown_pool(): mp_island._pool_size = None +def _evolve_func_ipy(ser_algo_pop): + # The evolve function that is actually run from the separate processes + # in ipyparallel_island. + import pickle + algo, pop = pickle.loads(ser_algo_pop) + new_pop = algo.evolve(pop) + return pickle.dumps((algo, new_pop)) + + class ipyparallel_island(object): """Ipyparallel island. @@ -537,6 +537,9 @@ def run_evolve(self, algo, pop): """ + # NOTE: as in the mp_island, we pre-serialize + # the algo and pop, so that we can catch + # serialization errors early. import pickle ser_algo_pop = pickle.dumps((algo, pop)) with self._view_lock: @@ -559,6 +562,7 @@ def get_extra_info(self): str: a string with extra information about the status of the island """ + from copy import deepcopy with self._view_lock: - d = self._lview.queue_status() + d = deepcopy(self._lview.queue_status()) return "\tQueue status:\n\t\n\t" + "\n\t".join(["(" + str(k) + ", " + str(d[k]) + ")" for k in d]) From 6643a5349f3017f18322ef0d241186e609b5e15b Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 17:50:22 +0100 Subject: [PATCH 15/35] Workaround try. [skip appveyor] --- pygmo/_island_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pygmo/_island_test.py b/pygmo/_island_test.py index ba3823fb1..95e91adb4 100644 --- a/pygmo/_island_test.py +++ b/pygmo/_island_test.py @@ -612,6 +612,7 @@ def run_basic_tests(self): from . import ipyparallel_island from copy import copy, deepcopy from pickle import dumps, loads + import gc to = .5 try: isl = island(algo=de(), prob=rosenbrock(), @@ -675,3 +676,4 @@ def run_basic_tests(self): isl.wait() self.assertTrue("**error occurred**" in repr(isl)) self.assertRaises(RuntimeError, lambda: isl.wait_check()) + gc.collect() From e42ada397ba1d5525785bb2b949ca4a9d7a43521 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 18:03:33 +0100 Subject: [PATCH 16/35] Another approach. [skip appveyor] --- pygmo/_island_test.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pygmo/_island_test.py b/pygmo/_island_test.py index 95e91adb4..2121dd5aa 100644 --- a/pygmo/_island_test.py +++ b/pygmo/_island_test.py @@ -612,7 +612,6 @@ def run_basic_tests(self): from . import ipyparallel_island from copy import copy, deepcopy from pickle import dumps, loads - import gc to = .5 try: isl = island(algo=de(), prob=rosenbrock(), @@ -669,11 +668,10 @@ def run_basic_tests(self): return # Check exception transport. - for _ in range(1000): + for _ in range(100): isl = island(algo=de(), prob=_prob( lambda x, y: x + y), size=2, udi=ipyparallel_island(timeout=to + .3)) isl.evolve() isl.wait() self.assertTrue("**error occurred**" in repr(isl)) self.assertRaises(RuntimeError, lambda: isl.wait_check()) - gc.collect() From 5d3356b41ad347062ab910822c4876ee73bac7a3 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 18:20:13 +0100 Subject: [PATCH 17/35] WIP [skip appveyor] --- pygmo/_island_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmo/_island_test.py b/pygmo/_island_test.py index 2121dd5aa..ba658af5c 100644 --- a/pygmo/_island_test.py +++ b/pygmo/_island_test.py @@ -668,7 +668,7 @@ def run_basic_tests(self): return # Check exception transport. - for _ in range(100): + for _ in range(10): isl = island(algo=de(), prob=_prob( lambda x, y: x + y), size=2, udi=ipyparallel_island(timeout=to + .3)) isl.evolve() From 1c6acf45c818f31965edabc3344af03b7e6eb884 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 18:36:37 +0100 Subject: [PATCH 18/35] Evolve the workaround. [skip appveyor] --- tools/install_travis.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/install_travis.sh b/tools/install_travis.sh index 29afd5595..acfaad7df 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -46,7 +46,11 @@ elif [[ "${PAGMO_BUILD}" == Python* ]]; then sleep 20; # Move out of the build dir. cd ../tools - python -c "import pygmo; pygmo.test.run_test_suite(1)"; + if [[ "${PAGMO_BUILD}" == Python3* ]]; then + python -c "import pygmo; pygmo.test.run_test_suite(1)"; + else + python -c "import pygmo; pygmo.test.run_test_suite()"; + fi # Additional serialization tests. python travis_additional_tests.py; From 62c3949fc563ec0269e67f8026c00a5398731bb2 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 19:21:39 +0100 Subject: [PATCH 19/35] More WIP [skip appveyor] --- tools/install_docker.sh | 2 +- tools/install_travis.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/install_docker.sh b/tools/install_docker.sh index 087317f02..ef8f774bc 100644 --- a/tools/install_docker.sh +++ b/tools/install_docker.sh @@ -75,7 +75,7 @@ if [[ ${PAGMO_BUILD} == *27m ]]; then # which will make some tests fail. Just try to import pygmo in this case. /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo" else - /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo; pygmo.test.run_test_suite(1)" + /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo; pygmo.test.run_test_suite(0)" fi # Upload to pypi. This variable will contain something if this is a tagged build (vx.y.z), otherwise it will be empty. diff --git a/tools/install_travis.sh b/tools/install_travis.sh index acfaad7df..addc2634e 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -153,7 +153,7 @@ elif [[ "${PAGMO_BUILD}" == OSXPython* ]]; then sleep 20; # Move out of the build dir. cd ../tools - python -c "import pygmo; pygmo.test.run_test_suite(1)" + python -c "import pygmo; pygmo.test.run_test_suite(0)" # Additional serialization tests. # python travis_additional_tests.py From 743ad464156370182b5baf5a79a6041e67a996ff Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 20:58:22 +0100 Subject: [PATCH 20/35] Another go [skip appveyor] --- tools/install_travis.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/install_travis.sh b/tools/install_travis.sh index addc2634e..2f5ca43ca 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -136,6 +136,9 @@ elif [[ "${PAGMO_BUILD}" == Python* ]]; then fi done elif [[ "${PAGMO_BUILD}" == OSXPython* ]]; then + sysctl -w kern.maxfiles=20480 + sysctl -w kern.maxfilesperproc=18000 + export CXX=clang++ export CC=clang # Install pagmo first. From f067494e8598a11df583f2008ea5e09e75893268 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 22:08:43 +0100 Subject: [PATCH 21/35] Another try [skip appveyor] --- tools/install_travis.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/install_travis.sh b/tools/install_travis.sh index 2f5ca43ca..83d949395 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -136,8 +136,7 @@ elif [[ "${PAGMO_BUILD}" == Python* ]]; then fi done elif [[ "${PAGMO_BUILD}" == OSXPython* ]]; then - sysctl -w kern.maxfiles=20480 - sysctl -w kern.maxfilesperproc=18000 + ulimit -S -n 2048 export CXX=clang++ export CC=clang From a0411c1d8c9241ea1eb5f14e0391ee0009f32155 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 23:43:13 +0100 Subject: [PATCH 22/35] Add py27 test on circleci. [skip appveyor] --- .circleci/config.yml | 11 +++- tools/circleci_bionic_gcc7_conda_py27.sh | 67 ++++++++++++++++++++++++ tools/circleci_bionic_gcc7_conda_py38.sh | 22 +++++++- 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 tools/circleci_bionic_gcc7_conda_py27.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index dd77785c6..e5bb3760b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,6 +9,14 @@ jobs: - run: name: Build and test command: bash ./tools/circleci_bionic_gcc7_conda_py38.sh + bionic_gcc7_conda_py27: + docker: + - image: circleci/buildpack-deps:bionic + steps: + - checkout + - run: + name: Build and test + command: bash ./tools/circleci_bionic_gcc7_conda_py27.sh bionic_gcc7_coverage: docker: - image: circleci/buildpack-deps:bionic @@ -46,7 +54,8 @@ workflows: version: 2 all_builds: jobs: - - bionic_gcc7_conda_py38 + # - bionic_gcc7_conda_py38 + - bionic_gcc7_conda_py27 # - bionic_gcc7_coverage # - cosmic_gcc8_asan # - cosmic_clang7 diff --git a/tools/circleci_bionic_gcc7_conda_py27.sh b/tools/circleci_bionic_gcc7_conda_py27.sh new file mode 100644 index 000000000..84a349a2a --- /dev/null +++ b/tools/circleci_bionic_gcc7_conda_py27.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Echo each command +set -x + +# Exit on error. +set -e + +# Core deps. +sudo apt-get install build-essential wget + +# Install conda+deps. +wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh +export deps_dir=$HOME/local +export PATH="$HOME/miniconda/bin:$PATH" +export PATH="$deps_dir/bin:$PATH" +bash miniconda.sh -b -p $HOME/miniconda +conda config --add channels conda-forge --force +conda_pkgs="cmake eigen nlopt ipopt boost boost-cpp tbb tbb-devel python=2.7 numpy cloudpickle dill numba pip ipyparallel" +conda create -q -p $deps_dir -y +source activate $deps_dir +conda install $conda_pkgs -y + +# Build/install pagmo. +mkdir build +cd build +cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_TESTS=no -DPAGMO_WITH_EIGEN3=yes -DPAGMO_WITH_NLOPT=yes -DPAGMO_WITH_IPOPT=yes -DBoost_NO_BOOST_CMAKE=ON +make -j2 VERBOSE=1 install + +# Build/install pygmo. +cd .. +mkdir build_py +cd build_py +cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DPAGMO_BUILD_PAGMO=no -DPAGMO_BUILD_PYGMO=yes -DBoost_NO_BOOST_CMAKE=ON +make -j2 VERBOSE=1 install + +# Start the ipyparallel cluster. +ipcluster start --daemonize=True; +# Give some time for the cluster to start up. +sleep 20; + +# Run the tests. +cd ../tools +python -c "import pygmo; pygmo.test.run_test_suite(1); pygmo.mp_island.shutdown_pool()"; + +# Additional serialization tests. +python travis_additional_tests.py; + +# AP examples. +cd ../ap_examples/uda_basic; +mkdir build; +cd build; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +make install VERBOSE=1; +cd ../../; +python test1.py + +cd udp_basic; +mkdir build; +cd build; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +make install VERBOSE=1; +cd ../../; +python test2.py + +set +e +set +x diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index 2131b5ac7..f070025ba 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -35,8 +35,28 @@ cmake ../ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREF make -j2 VERBOSE=1 install # Run the tests. -cd / +cd ../tools python -c "import pygmo; pygmo.test.run_test_suite(1); pygmo.mp_island.shutdown_pool()"; +# Additional serialization tests. +python travis_additional_tests.py; + +# AP examples. +cd ../ap_examples/uda_basic; +mkdir build; +cd build; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +make install VERBOSE=1; +cd ../../; +python test1.py + +cd udp_basic; +mkdir build; +cd build; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +make install VERBOSE=1; +cd ../../; +python test2.py + set +e set +x From 325f3e128fba8119c383dc23188abb256a531beb Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Fri, 6 Dec 2019 23:50:14 +0100 Subject: [PATCH 23/35] Evolving the implementation. [skip appveyor] --- tools/circleci_bionic_gcc7_conda_py27.sh | 2 +- tools/install_docker.sh | 2 +- tools/install_travis.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/circleci_bionic_gcc7_conda_py27.sh b/tools/circleci_bionic_gcc7_conda_py27.sh index 84a349a2a..4ea36f908 100644 --- a/tools/circleci_bionic_gcc7_conda_py27.sh +++ b/tools/circleci_bionic_gcc7_conda_py27.sh @@ -41,7 +41,7 @@ sleep 20; # Run the tests. cd ../tools -python -c "import pygmo; pygmo.test.run_test_suite(1); pygmo.mp_island.shutdown_pool()"; +python -c "import pygmo; pygmo.test.run_test_suite(); pygmo.mp_island.shutdown_pool()"; # Additional serialization tests. python travis_additional_tests.py; diff --git a/tools/install_docker.sh b/tools/install_docker.sh index ef8f774bc..81a9dc053 100644 --- a/tools/install_docker.sh +++ b/tools/install_docker.sh @@ -75,7 +75,7 @@ if [[ ${PAGMO_BUILD} == *27m ]]; then # which will make some tests fail. Just try to import pygmo in this case. /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo" else - /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo; pygmo.test.run_test_suite(0)" + /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo; pygmo.test.run_test_suite()" fi # Upload to pypi. This variable will contain something if this is a tagged build (vx.y.z), otherwise it will be empty. diff --git a/tools/install_travis.sh b/tools/install_travis.sh index 83d949395..95b5993f5 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -155,7 +155,7 @@ elif [[ "${PAGMO_BUILD}" == OSXPython* ]]; then sleep 20; # Move out of the build dir. cd ../tools - python -c "import pygmo; pygmo.test.run_test_suite(0)" + python -c "import pygmo; pygmo.test.run_test_suite()" # Additional serialization tests. # python travis_additional_tests.py From fbe191984d384c90e49e57aa963926416750988e Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 00:02:11 +0100 Subject: [PATCH 24/35] More verbosity. [skip appveyor] --- tools/travis_additional_tests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/travis_additional_tests.py b/tools/travis_additional_tests.py index 37aec415f..8c7ba045a 100644 --- a/tools/travis_additional_tests.py +++ b/tools/travis_additional_tests.py @@ -38,6 +38,7 @@ def test1(): archi = pg.archipelago(n=6, algo=algo, prob=prob, pop_size=70) archi.evolve() archi.wait_check() + print("end of test1") def test2(): @@ -46,6 +47,7 @@ def test2(): archi = pg.archipelago(n=6, algo=mma, prob=p_toy, pop_size=1) archi.evolve() archi.wait_check() + print("end of test2") if __name__ == '__main__': From ab39946a3d085148aa2c21857ce4d13eefca1394 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 00:23:18 +0100 Subject: [PATCH 25/35] More debug. --- .circleci/config.yml | 2 +- tools/circleci_bionic_gcc7_conda_py27.sh | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e5bb3760b..399b0a67f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,7 +54,7 @@ workflows: version: 2 all_builds: jobs: - # - bionic_gcc7_conda_py38 + - bionic_gcc7_conda_py38 - bionic_gcc7_conda_py27 # - bionic_gcc7_coverage # - cosmic_gcc8_asan diff --git a/tools/circleci_bionic_gcc7_conda_py27.sh b/tools/circleci_bionic_gcc7_conda_py27.sh index 4ea36f908..6c89524e4 100644 --- a/tools/circleci_bionic_gcc7_conda_py27.sh +++ b/tools/circleci_bionic_gcc7_conda_py27.sh @@ -41,6 +41,9 @@ sleep 20; # Run the tests. cd ../tools +ipcluster stop +ipcluster start --daemonize=True; +sleep 20; python -c "import pygmo; pygmo.test.run_test_suite(); pygmo.mp_island.shutdown_pool()"; # Additional serialization tests. From ba6316988470df146e50be8100ad8a459a29b990 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 00:33:52 +0100 Subject: [PATCH 26/35] More WIP [skip appveyor] --- tools/circleci_bionic_gcc7_conda_py27.sh | 10 +++++----- tools/circleci_bionic_gcc7_conda_py38.sh | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/circleci_bionic_gcc7_conda_py27.sh b/tools/circleci_bionic_gcc7_conda_py27.sh index 6c89524e4..31b5e654e 100644 --- a/tools/circleci_bionic_gcc7_conda_py27.sh +++ b/tools/circleci_bionic_gcc7_conda_py27.sh @@ -41,19 +41,19 @@ sleep 20; # Run the tests. cd ../tools -ipcluster stop -ipcluster start --daemonize=True; -sleep 20; python -c "import pygmo; pygmo.test.run_test_suite(); pygmo.mp_island.shutdown_pool()"; # Additional serialization tests. +ipcluster stop +ipcluster start --daemonize=True; +sleep 20; python travis_additional_tests.py; # AP examples. cd ../ap_examples/uda_basic; mkdir build; cd build; -cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../ -DBoost_NO_BOOST_CMAKE=ON; make install VERBOSE=1; cd ../../; python test1.py @@ -61,7 +61,7 @@ python test1.py cd udp_basic; mkdir build; cd build; -cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../ -DBoost_NO_BOOST_CMAKE=ON; make install VERBOSE=1; cd ../../; python test2.py diff --git a/tools/circleci_bionic_gcc7_conda_py38.sh b/tools/circleci_bionic_gcc7_conda_py38.sh index f070025ba..09a8e6448 100644 --- a/tools/circleci_bionic_gcc7_conda_py38.sh +++ b/tools/circleci_bionic_gcc7_conda_py38.sh @@ -45,7 +45,7 @@ python travis_additional_tests.py; cd ../ap_examples/uda_basic; mkdir build; cd build; -cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug -DBoost_NO_BOOST_CMAKE=ON ../; make install VERBOSE=1; cd ../../; python test1.py @@ -53,7 +53,7 @@ python test1.py cd udp_basic; mkdir build; cd build; -cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug ../; +cmake -DCMAKE_INSTALL_PREFIX=$deps_dir -DCMAKE_PREFIX_PATH=$deps_dir -DCMAKE_BUILD_TYPE=Debug -DBoost_NO_BOOST_CMAKE=ON ../; make install VERBOSE=1; cd ../../; python test2.py From 722a83174a3cacbd57a7075ea866ab9869d4db79 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 00:50:40 +0100 Subject: [PATCH 27/35] More WIP. [skip appveyor] --- tools/circleci_bionic_gcc7_conda_py27.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/circleci_bionic_gcc7_conda_py27.sh b/tools/circleci_bionic_gcc7_conda_py27.sh index 31b5e654e..18de03b5e 100644 --- a/tools/circleci_bionic_gcc7_conda_py27.sh +++ b/tools/circleci_bionic_gcc7_conda_py27.sh @@ -45,6 +45,7 @@ python -c "import pygmo; pygmo.test.run_test_suite(); pygmo.mp_island.shutdown_p # Additional serialization tests. ipcluster stop +sleep 20; ipcluster start --daemonize=True; sleep 20; python travis_additional_tests.py; From 28382f6d35c9df0602f2f20a986813d31dcf4846 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 01:04:00 +0100 Subject: [PATCH 28/35] More WIP. [skip appveyor] --- tools/travis_additional_tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/travis_additional_tests.py b/tools/travis_additional_tests.py index 8c7ba045a..a1db5bde2 100644 --- a/tools/travis_additional_tests.py +++ b/tools/travis_additional_tests.py @@ -53,3 +53,4 @@ def test2(): if __name__ == '__main__': test1() test2() + pg.mp_island.shutdown_pool() From dcea925fd61c7d3bd9b356901e3620a1bdeb9327 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 01:16:28 +0100 Subject: [PATCH 29/35] More debug. [skip appveyor] --- pygmo/core.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pygmo/core.cpp b/pygmo/core.cpp index d817fbaf4..cb857965f 100644 --- a/pygmo/core.cpp +++ b/pygmo/core.cpp @@ -190,6 +190,8 @@ bp::object test_object_serialization(const bp::object &o) // supermodule gets unloaded). void cleanup() { + std::cout << "starting C++ cleanup\n"; + problem_ptr.reset(); algorithm_ptr.reset(); @@ -203,6 +205,8 @@ void cleanup() r_policy_ptr.reset(); s_policy_ptr.reset(); + + std::cout << "C++ cleanup completed\n"; } // Serialization support for the population class. From b92bad7c24c857fb4f6585f6e1c9adff6db3bbb4 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 02:20:16 +0100 Subject: [PATCH 30/35] More tries [skip appveyor] --- pygmo/core.cpp | 4 ---- tools/travis_additional_tests.py | 12 ++++++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pygmo/core.cpp b/pygmo/core.cpp index cb857965f..d817fbaf4 100644 --- a/pygmo/core.cpp +++ b/pygmo/core.cpp @@ -190,8 +190,6 @@ bp::object test_object_serialization(const bp::object &o) // supermodule gets unloaded). void cleanup() { - std::cout << "starting C++ cleanup\n"; - problem_ptr.reset(); algorithm_ptr.reset(); @@ -205,8 +203,6 @@ void cleanup() r_policy_ptr.reset(); s_policy_ptr.reset(); - - std::cout << "C++ cleanup completed\n"; } // Serialization support for the population class. diff --git a/tools/travis_additional_tests.py b/tools/travis_additional_tests.py index a1db5bde2..7e59df958 100644 --- a/tools/travis_additional_tests.py +++ b/tools/travis_additional_tests.py @@ -1,32 +1,35 @@ -import pygmo as pg -import numpy as np - - # NOTE: a couple of serialization tests from: # https://github.com/esa/pagmo2/issues/106 + class toy_problem: def fitness(self, x): + import numpy as np return [np.sum(np.sin((x - .2)**2))] def get_bounds(self): + import numpy as np return (np.array([-1] * 3), np.array([1] * 3)) class toy_problem_2: def fitness(self, x): + import numpy as np return [np.sin(x[0] + x[1] - x[2])] def gradient(self, x): + import pygmo as pg return pg.estimate_gradient(lambda x: self.fitness(x), x) def get_bounds(self): + import numpy as np return (np.array([-1] * 3), np.array([1] * 3)) def test1(): + import pygmo as pg algo = pg.algorithm(pg.de(gen=1000, seed=126)) prob = pg.problem(toy_problem()) pop = pg.population(prob=prob, size=10) @@ -42,6 +45,7 @@ def test1(): def test2(): + import pygmo as pg mma = pg.algorithm(pg.nlopt("mma")) p_toy = pg.problem(toy_problem_2()) archi = pg.archipelago(n=6, algo=mma, prob=p_toy, pop_size=1) From 72022c459143e897f33065d66f3dd4efdf82b5a6 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 02:34:16 +0100 Subject: [PATCH 31/35] Partially revert. --- tools/travis_additional_tests.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tools/travis_additional_tests.py b/tools/travis_additional_tests.py index 7e59df958..a1db5bde2 100644 --- a/tools/travis_additional_tests.py +++ b/tools/travis_additional_tests.py @@ -1,35 +1,32 @@ +import pygmo as pg +import numpy as np + + # NOTE: a couple of serialization tests from: # https://github.com/esa/pagmo2/issues/106 - class toy_problem: def fitness(self, x): - import numpy as np return [np.sum(np.sin((x - .2)**2))] def get_bounds(self): - import numpy as np return (np.array([-1] * 3), np.array([1] * 3)) class toy_problem_2: def fitness(self, x): - import numpy as np return [np.sin(x[0] + x[1] - x[2])] def gradient(self, x): - import pygmo as pg return pg.estimate_gradient(lambda x: self.fitness(x), x) def get_bounds(self): - import numpy as np return (np.array([-1] * 3), np.array([1] * 3)) def test1(): - import pygmo as pg algo = pg.algorithm(pg.de(gen=1000, seed=126)) prob = pg.problem(toy_problem()) pop = pg.population(prob=prob, size=10) @@ -45,7 +42,6 @@ def test1(): def test2(): - import pygmo as pg mma = pg.algorithm(pg.nlopt("mma")) p_toy = pg.problem(toy_problem_2()) archi = pg.archipelago(n=6, algo=mma, prob=p_toy, pop_size=1) From 47d9d6f97830fdb943cd168ec469048e91e45a11 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 16:08:05 +0100 Subject: [PATCH 32/35] Try another ipyparallel_island approach. --- pygmo/__init__.py | 1 + pygmo/_island_test.py | 20 ++++--- pygmo/_py_islands.py | 122 +++++++++++++++++++++++++----------------- 3 files changed, 88 insertions(+), 55 deletions(-) diff --git a/pygmo/__init__.py b/pygmo/__init__.py index 7cc0aa7ad..a1ae9196d 100644 --- a/pygmo/__init__.py +++ b/pygmo/__init__.py @@ -837,6 +837,7 @@ def get_serialization_backend(): def _cleanup(): mp_island.shutdown_pool() + ipyparallel_island.shutdown_view() _cpp_cleanup() diff --git a/pygmo/_island_test.py b/pygmo/_island_test.py index ba658af5c..b2f68dcbd 100644 --- a/pygmo/_island_test.py +++ b/pygmo/_island_test.py @@ -612,18 +612,24 @@ def run_basic_tests(self): from . import ipyparallel_island from copy import copy, deepcopy from pickle import dumps, loads + + ipyparallel_island.shutdown_view() + ipyparallel_island.shutdown_view() + ipyparallel_island.shutdown_view() + to = .5 + isl = island(algo=de(), prob=rosenbrock(), + size=25, udi=ipyparallel_island()) + ipyparallel_island.shutdown_view() try: - isl = island(algo=de(), prob=rosenbrock(), - size=25, udi=ipyparallel_island(timeout=to)) + ipyparallel_island.init_view(timeout=to) except OSError: return isl = island(algo=de(), prob=rosenbrock(), - size=25, udi=ipyparallel_island(timeout=to)) - isl = island(algo=de(), prob=rosenbrock(), - size=25, udi=ipyparallel_island(timeout=to + .3)) + size=25, udi=ipyparallel_island()) self.assertEqual(isl.get_name(), "Ipyparallel island") self.assertTrue(isl.get_extra_info() != "") + ipyparallel_island.shutdown_view() isl.evolve(20) isl.wait_check() isl.evolve(20) @@ -632,7 +638,7 @@ def run_basic_tests(self): # Check the picklability of a problem storing a lambda. isl = island(algo=de(), prob=_prob(lambda x, y: x + y), - size=25, udi=ipyparallel_island(timeout=to + .3)) + size=25, udi=ipyparallel_island()) isl.evolve() isl.wait_check() @@ -670,7 +676,7 @@ def run_basic_tests(self): # Check exception transport. for _ in range(10): isl = island(algo=de(), prob=_prob( - lambda x, y: x + y), size=2, udi=ipyparallel_island(timeout=to + .3)) + lambda x, y: x + y), size=2, udi=ipyparallel_island()) isl.evolve() isl.wait() self.assertTrue("**error occurred**" in repr(isl)) diff --git a/pygmo/_py_islands.py b/pygmo/_py_islands.py index 0342d54bc..59884b33d 100644 --- a/pygmo/_py_islands.py +++ b/pygmo/_py_islands.py @@ -455,11 +455,11 @@ class ipyparallel_island(object): """Ipyparallel island. This user-defined island (UDI) will dispatch evolution tasks to an ipyparallel cluster. - Upon construction, an instance of this UDI will first initialise an :class:`ipyparallel.Client` - object, and then extract an :class:`ipyparallel.LoadBalancedView` object from it that will - be used to submit evolution tasks to the cluster. The arguments to the constructor of this - class will be passed without modifications to the constructor of the :class:`ipyparallel.Client` - object that will be created internally. + The communication with the cluster is managed via an :class:`ipyparallel.LoadBalancedView` + instance which is created either implicitly when the first evolution is run, or explicitly + via the :func:`~pygmo.ipyparallel_island.init_view()` method. The + :class:`~ipyparallel.LoadBalancedView` instance is unique and shared among all the + ipyparallel islands. .. seealso:: @@ -467,59 +467,76 @@ class will be passed without modifications to the constructor of the :class:`ipy """ - def __init__(self, *args, **kwargs): - self._lview = self._init(*args, **kwargs) + # Static variables for the view. + _view_lock = _Lock() + _view = None - def _init(self, *args, **kwargs): - # A small helper function which will do the following: - # * create a new client from scratch, - # * store a copy of the input arguments as class members, - # * create a LoadBalancedView from the client, - # * create a lock to regulate access to the view, - # * return the view. - from ipyparallel import Client - from copy import deepcopy + def __init__(self): + pass - # Save the init arguments. - self._args = deepcopy(args) - self._kwargs = deepcopy(kwargs) + @staticmethod + def init_view(*args, **kwargs): + """Init the ipyparallel view. + + .. versionadded:: 2.12 + + This method will initialise the :class:`ipyparallel.LoadBalancedView` + which is used by all ipyparallel islands to submit the evolution tasks + to an ipyparallel cluster. The input arguments are forwarded + to the construction of an :class:`ipyparallel.Client` instance, + from which the :class:`~ipyparallel.LoadBalancedView` instance + is then fetched via the :func:`ipyparallel.Client.load_balanced_view()` + method. + + Note that usually it is not necessary to explicitly invoke this + method: a :class:`~ipyparallel.LoadBalancedView` is automatically + constructed with default settings the first time an evolution task + is submitted to an ipyparallel island. This method should be used + only if it is necessary to pass custom arguments to the construction + of the :class:`~ipyparallel.Client` object from which the + :class:`~ipyparallel.LoadBalancedView` is fetched. - # Create the client. - rc = Client(*args, **kwargs) + Raises: - # NOTE: we need to regulate access to the view because, - # while run_evolve() is running in a separate thread, we - # could be doing other things involving the view (e.g., - # asking extra_info()). Thus, create the lock here. - self._view_lock = _Lock() + unspecified: any exception thrown by the constructor of :class:`~ipyparallel.Client` - return rc.load_balanced_view() + """ + from ipyparallel import Client + with ipyparallel_island._view_lock: + ipyparallel_island._view = Client( + *args, **kwargs).load_balanced_view() - def __copy__(self): - # For copy/deepcopy, construct a new instance - # with the same arguments used to construct self. - return ipyparallel_island(*self._args, **self._kwargs) + @staticmethod + def shutdown_view(): + """Destroy the ipyparallel view. - def __deepcopy__(self, d): - return self.__copy__() + .. versionadded:: 2.12 - def __getstate__(self): - # For pickle/unpickle, we employ the construction - # arguments, which will be used to re-init the class - # during unpickle. - from copy import deepcopy - return deepcopy(self._args), deepcopy(self._kwargs) + This method will destroy the :class:`ipyparallel.LoadBalancedView` + currently being used by the ipyparallel islands for submitting + evolution tasks to an ipyparallel cluster. The view can be re-inited + implicitly by submitting a new evolution task, or by invoking + the :func:`~pygmo.ipyparallel_island.init_view()` method. - def __setstate__(self, state): - self._lview = self._init(*state[0], **state[1]) + """ + import gc + with ipyparallel_island._view_lock: + if ipyparallel_island._view is None: + return + + old_view = ipyparallel_island._view + ipyparallel_island._view = None + del(old_view) + gc.collect() def run_evolve(self, algo, pop): """Evolve population. This method will evolve the input :class:`~pygmo.population` *pop* using the input :class:`~pygmo.algorithm` *algo*, and return *algo* and the evolved population. The evolution - task is submitted to the ipyparallel cluster via an internal :class:`ipyparallel.LoadBalancedView` - instance initialised during the construction of the island. + task is submitted to the ipyparallel cluster via a global :class:`ipyparallel.LoadBalancedView` + instance initialised either implicitly by the first invocation of this method, + or by an explicit call to the :func:`~pygmo.ipyparallel_island.init_view()` method. Args: @@ -532,7 +549,8 @@ def run_evolve(self, algo, pop): Raises: - unspecified: any exception thrown during the evolution, or by submitting the evolution task + unspecified: any exception thrown by the evolution, by the creation of a + :class:`ipyparallel.LoadBalancedView`, or by the sumission of the evolution task to the ipyparallel cluster @@ -542,8 +560,13 @@ def run_evolve(self, algo, pop): # serialization errors early. import pickle ser_algo_pop = pickle.dumps((algo, pop)) - with self._view_lock: - ret = self._lview.apply_async(_evolve_func_ipy, ser_algo_pop) + with ipyparallel_island._view_lock: + if ipyparallel_island._view is None: + from ipyparallel import Client + ipyparallel_island._view = Client().load_balanced_view() + ret = ipyparallel_island._view.apply_async( + _evolve_func_ipy, ser_algo_pop) + return pickle.loads(ret.get()) def get_name(self): @@ -563,6 +586,9 @@ def get_extra_info(self): """ from copy import deepcopy - with self._view_lock: - d = deepcopy(self._lview.queue_status()) + with ipyparallel_island._view_lock: + if ipyparallel_island._view is None: + return "\tNo cluster view has been created yet" + else: + d = deepcopy(ipyparallel_island._view.queue_status()) return "\tQueue status:\n\t\n\t" + "\n\t".join(["(" + str(k) + ", " + str(d[k]) + ")" for k in d]) From 35178f647990fadf06198513b2ba76bc613af828 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 18:28:05 +0100 Subject: [PATCH 33/35] More WIP, re-enable builds. --- .circleci/config.yml | 8 ++++---- .travis.yml | 11 ----------- ap_examples/test1.py | 1 + ap_examples/test2.py | 1 + tools/circleci_bionic_gcc7_conda_py27.sh | 2 +- tools/install_deps.sh | 2 +- tools/install_docker.sh | 2 +- tools/install_travis.sh | 12 ++---------- 8 files changed, 11 insertions(+), 28 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 399b0a67f..7d1a8af0c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -56,7 +56,7 @@ workflows: jobs: - bionic_gcc7_conda_py38 - bionic_gcc7_conda_py27 - # - bionic_gcc7_coverage - # - cosmic_gcc8_asan - # - cosmic_clang7 - # - bionic_clang6_release + - bionic_gcc7_coverage + - cosmic_gcc8_asan + - cosmic_clang7 + - bionic_clang6_release diff --git a/.travis.yml b/.travis.yml index 77cb3e313..84d38a60d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,17 +51,6 @@ matrix: packages: - gcc-4.8 - g++-4.8 - - env: PAGMO_BUILD="Python27" - dist: trusty - compiler: gcc - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.8 - - g++-4.8 - env: PAGMO_BUILD="OSXDebug" os: osx osx_image: xcode6.4 diff --git a/ap_examples/test1.py b/ap_examples/test1.py index 33d827939..cd3554377 100644 --- a/ap_examples/test1.py +++ b/ap_examples/test1.py @@ -26,4 +26,5 @@ def fitness(self, a): isl = pygmo.island(algo=ub, prob=py_udp(), size=20) isl.evolve() isl.wait_check() + pygmo.mp_island.shutdown_pool() print("All good!") diff --git a/ap_examples/test2.py b/ap_examples/test2.py index f2a428004..a533e37cb 100644 --- a/ap_examples/test2.py +++ b/ap_examples/test2.py @@ -24,4 +24,5 @@ def evolve(self, pop): isl = pygmo.island(algo=py_uda(), prob=ub, size=20) isl.evolve() isl.wait_check() + pygmo.mp_island.shutdown_pool() print("All good!") diff --git a/tools/circleci_bionic_gcc7_conda_py27.sh b/tools/circleci_bionic_gcc7_conda_py27.sh index 18de03b5e..5ddd4baee 100644 --- a/tools/circleci_bionic_gcc7_conda_py27.sh +++ b/tools/circleci_bionic_gcc7_conda_py27.sh @@ -41,7 +41,7 @@ sleep 20; # Run the tests. cd ../tools -python -c "import pygmo; pygmo.test.run_test_suite(); pygmo.mp_island.shutdown_pool()"; +python -c "import pygmo; pygmo.test.run_test_suite(1); pygmo.mp_island.shutdown_pool()"; # Additional serialization tests. ipcluster stop diff --git a/tools/install_deps.sh b/tools/install_deps.sh index 96c8fc50e..f5c72dee5 100755 --- a/tools/install_deps.sh +++ b/tools/install_deps.sh @@ -21,7 +21,7 @@ if [[ "${PAGMO_BUILD}" != manylinux* ]]; then if [[ "${PAGMO_BUILD}" == "Python37" || "${PAGMO_BUILD}" == "OSXPython37" ]]; then conda_pkgs="$conda_pkgs python=3.7 numpy cloudpickle dill ipyparallel numba pip" - elif [[ "${PAGMO_BUILD}" == "Python27" || "${PAGMO_BUILD}" == "OSXPython27" ]]; then + elif [[ "${PAGMO_BUILD}" == "OSXPython27" ]]; then conda_pkgs="$conda_pkgs python=2.7 numpy cloudpickle dill ipyparallel numba" fi diff --git a/tools/install_docker.sh b/tools/install_docker.sh index 81a9dc053..087317f02 100644 --- a/tools/install_docker.sh +++ b/tools/install_docker.sh @@ -75,7 +75,7 @@ if [[ ${PAGMO_BUILD} == *27m ]]; then # which will make some tests fail. Just try to import pygmo in this case. /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo" else - /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo; pygmo.test.run_test_suite()" + /opt/python/${PYTHON_DIR}/bin/python -c "import pygmo; pygmo.test.run_test_suite(1)" fi # Upload to pypi. This variable will contain something if this is a tagged build (vx.y.z), otherwise it will be empty. diff --git a/tools/install_travis.sh b/tools/install_travis.sh index 95b5993f5..2fd17c26f 100755 --- a/tools/install_travis.sh +++ b/tools/install_travis.sh @@ -46,11 +46,7 @@ elif [[ "${PAGMO_BUILD}" == Python* ]]; then sleep 20; # Move out of the build dir. cd ../tools - if [[ "${PAGMO_BUILD}" == Python3* ]]; then - python -c "import pygmo; pygmo.test.run_test_suite(1)"; - else - python -c "import pygmo; pygmo.test.run_test_suite()"; - fi + python -c "import pygmo; pygmo.test.run_test_suite(1)"; # Additional serialization tests. python travis_additional_tests.py; @@ -71,10 +67,6 @@ elif [[ "${PAGMO_BUILD}" == Python* ]]; then make install VERBOSE=1; cd ../../; python test2.py - if [[ "${PAGMO_BUILD}" == "Python27" ]]; then - # Stop here if this is the Python27 build. Docs are produced and uploaded only in the Python37 build. - exit 0; - fi # Documentation. cd ../build @@ -155,7 +147,7 @@ elif [[ "${PAGMO_BUILD}" == OSXPython* ]]; then sleep 20; # Move out of the build dir. cd ../tools - python -c "import pygmo; pygmo.test.run_test_suite()" + python -c "import pygmo; pygmo.test.run_test_suite(1)" # Additional serialization tests. # python travis_additional_tests.py From e6c83345c8eb699a048b260825953e6c2007d6e3 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 18:41:55 +0100 Subject: [PATCH 34/35] More cleanup. [skip appveyor] --- tools/circleci_bionic_gcc7_conda_py27.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/circleci_bionic_gcc7_conda_py27.sh b/tools/circleci_bionic_gcc7_conda_py27.sh index 5ddd4baee..58a7c02f2 100644 --- a/tools/circleci_bionic_gcc7_conda_py27.sh +++ b/tools/circleci_bionic_gcc7_conda_py27.sh @@ -44,10 +44,6 @@ cd ../tools python -c "import pygmo; pygmo.test.run_test_suite(1); pygmo.mp_island.shutdown_pool()"; # Additional serialization tests. -ipcluster stop -sleep 20; -ipcluster start --daemonize=True; -sleep 20; python travis_additional_tests.py; # AP examples. From ac2f36916271b5bcd59610861ac63a0eb4b8e2f7 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 7 Dec 2019 22:44:13 +0100 Subject: [PATCH 35/35] Small doc fix, changelog update. --- doc/sphinx/changelog.rst | 9 +++++ doc/sphinx/docs/cpp/algorithms/nspso.rst | 44 ++++++++++++++---------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/doc/sphinx/changelog.rst b/doc/sphinx/changelog.rst index a7101fee6..7e2705313 100644 --- a/doc/sphinx/changelog.rst +++ b/doc/sphinx/changelog.rst @@ -18,6 +18,15 @@ New - Implement the NSPSO algorithm (`#314 `__). +Changes +~~~~~~~ + +- **BREAKING**: the mechanism for managing the + interaction of an :class:`~pygmo.ipyparallel_island` + with an ipyparallel cluster has changed. Please refer + to the documentation for details + (`#368 `__). + Fix ~~~ diff --git a/doc/sphinx/docs/cpp/algorithms/nspso.rst b/doc/sphinx/docs/cpp/algorithms/nspso.rst index a229683f4..23bf6fb48 100644 --- a/doc/sphinx/docs/cpp/algorithms/nspso.rst +++ b/doc/sphinx/docs/cpp/algorithms/nspso.rst @@ -58,24 +58,32 @@ Non dominated sorting particle swarm optimization(NSPSO) .. cpp:function:: void set_verbosity(unsigned level) - Sets the algorithm verbosity: sets the verbosity level of the screen ouput and of the log returned by ``get_log()`. *level* can be: - - 0: no verbosity. - - >0: will print and log one line each *level* generations. - Example (verbosity 1, where Gen, is the generation number, Fevals the number of function evaluations used; also, the ideal point of the current population follows cropped to its 5th component): - .. code-block:: c++ - :linenos: - - Gen: Fevals: ideal1: ideal2: ideal3: ideal4: ideal5: ... : - 1 52 0.0586347 0.0587097 0.0586892 0.0592426 0.0614239 - 2 104 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 3 156 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 4 208 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 5 260 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 6 312 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 7 364 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 8 416 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 9 468 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 - 10 520 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + Sets the algorithm verbosity: sets the verbosity level + of the screen ouput and of the log returned by ``get_log()``. + *level* can be: + + * 0: no verbosity. + * >0: will print and log one line each *level* generations. + + Example (verbosity 1, where Gen, is the generation number, + Fevals the number of function evaluations used; also, the + ideal point of the current population follows cropped to its + 5th component): + + .. code-block:: c++ + :linenos: + + Gen: Fevals: ideal1: ideal2: ideal3: ideal4: ideal5: ... : + 1 52 0.0586347 0.0587097 0.0586892 0.0592426 0.0614239 + 2 104 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 3 156 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 4 208 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 5 260 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 6 312 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 7 364 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 8 416 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 9 468 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 + 10 520 0.00899252 0.00899395 0.00945782 0.0106282 0.0276778 .. cpp:function:: unsigned get_verbosity() const