A parallel global multiobjective framework for optimization: pagmo

Efficient implementantions of bio-inspired and evolutionary algorithms are sided to state-ofthe-art optimization algorithms (Simplex Methods, SQP methods, interior points methods, etc.) and can be used concurrently (also together with algorithms coded by the user) to build an optimization pipeline exploiting algorithmic cooperation via the asynchronous, generalized island model (Izzo, Ruciński, & Biscani, 2012).

pagmo can be used to solve constrained, unconstrained, single objective, multiple objectives, continuous and integer optimization problems, stochastic and deterministic problems, as well as to perform research on novel algorithms and paradigms and easily compare them to stateof-the-art implementations of established ones.
For users that are more comfortable with the Python language, the package pygmo provides a complete set of Python bindings for pagmo closely following the C++ API.

The optimization problem
In pagmo optimization problems are considered to be in the form: find: lb ≤ x ≤ ub to minimize: f (x, s) ∈ R n obj subject to: c e (x, s) = 0 c i (x, s) ≤ 0 where x ∈ R ncx × Z nix is called a decision vector or chromosome, and is made of n cx real numbers and n ix integers (all represented as doubles). The total problem dimension is then indicated with n x = n cx + n ix . lb, ub ∈ R ncx × Z nix are the box-bounds, f : R ncx × Z nix → R n obj define the objectives, c e : R ncx × Z nix → R nec are nonlinear equality constraints, and c i : R ncx × Z nix → R nic are nonlinear inequality constraints. Note that the objectives and constraints also depend on an added value s representing some stochastic variable. Both equality and inequality constraints are considered as satisfied whenever their definition is met within a tolerance c tol .
Note that there is no special treatment of a possible linear part of the objectives or constraints, and as such solvers in pagmo cannot take advantage of the special structure of linear programming tasks.
Given the generic form used to represent a problem, pagmo is suitable to solve a broad range of optimization problems, ranging from single and multiobjective problems to box-bounded and nonlinearly constrained problems to stochastic problems to continuous, integer and mixed integer problems.

The pagmo jargon
The discussion on the relation between artificial evolution and mathematical optimization is an interesting one (Smith, 1978). In pagmo optimization, of all types, is regarded as a form of evolution. Solving an optimization problem is, in pagmo, described as evolving a population. Each decision vector is thus referred to also as a chromosome and its fitness is defined as a vector containing objectives, equality constraints and inequality constraints in this order. Regardless of whether the user is using, as a solver, a sequential quadratic programming approach, an interior point optimizer, an evolutionary strategy or some metaheuristic, in pagmo the user will always have to call a method called evolve to improve over the initial solutions stored in a population. A population may or may not live in an island.
When it does, its evolution is delegated to a different computational unit (a process, thread or remote CPU). Stretching this jargon even further, in pagmo a set of islands optimizing the same problem is called an archipelago. When solutions are also exchanged among populations living on the same archipelago, the quality of the overall optimization is often improved (Izzo et al., 2012). This exchange of information among different solvers is referred to as migrations and the allowed migration routes (affecting the overall process significantly (Ruciński, Izzo, & Biscani, 2010)) as the topology of the archipelago.

Exploiting parallelism
Parallelizing optimization tasks in a generic fashion is one of the leading software design principles of pagmo. According to the type of optimization task, and in particular to the computational weight of computing the problem fitness function, a different granularity of the parallelization option may be ideal.

Island Model
As a coarse-grained parallelism, pagmo offers an implementation of the so-called generalized island model (Izzo et al., 2012). Early ideas on distributing genetic algorithms over multiple CPUs were developed in the early 90s by Reiko Tanese, one of John Holland's students (Tanese, 1989). The idea that migrations could improve the quality of the solutions obtained for some optimization task as well as offer a quasi-linear speedup was, though, confined mainly to genetic algorithms and called island model. In pagmo any solver, inspired by the Darwinian evolution paradigm, by swarm intelligence, by any meta-heuristics or based on mathematical optimality conditions is allowed to exchange information during an evolution with other solvers connected to it via defined migration paths.

Concurrent fitness evaluations
In some situations it is preferable to parallelize the evolution pipeline at a finer grain (e.g., if the objective function evaluation is extremely costly). For this purpose, pagmo provides a batch fitness evaluation framework which can be used by selected algorithms to perform in parallel the objective function evaluation of multiple independent decision vectors. The parallel evaluation can be performed by multiple threads, processes, nodes in an HPC cluster or even by GPU devices (via, e.g., OpenCL or CUDA). In this last case it is up to the user to code a user-defined batch fitness evaluator.

Related projects / frameworks
A large number of projects, open source as well as commercial, exist whose functionalities overlap, at least partially, with those of pagmo. On the one hand, projects such as jMetal (Durillo & Nebro, 2011), DEAP (Fortin, De Rainville, Gardner, Parizeau, & Gagné, 2012), ParadisEO (Cahon, Melab, & Talbi, 2004) and others originate from the metaheuristic community and, essentially, offer implementations of a number of derivative-free solvers suitable for multi-objective and single-objective problems, some with (fine-grained) parallelization capabilities. On the other hand, projects like AMPL (Fourer, Gay, & Kernighan, 2003) or GAMS originate from the operational research community and offer modelling languages able to represent generic optimization problems and to forward them, together with the jacobians and hessians needed, to compatible solvers. A third type of projects, like NLOpt (Johnson, 2014) or the Scipy (Virtanen et al., 2020) optimize module offer a number of solvers without making much distinction between heuristic, derivative-free or local deterministic solvers. The project pagmo has most of the capabilities of the above mentioned software packages integrated in the same ecosystem as it offers a large variety of parallelization modes and, above all, the possibility to code and easily wrap new (or third party) solvers, problems and parallelization strategies. A unique characteristic of pagmo to be highlighted here, is the presence of an island model implementation (Izzo et al., 2012) that can flexibly distribute any solver, original, user-implemented or third-party on multiple CPUs.

Code Design C++
pagmo is written in standard-compliant C++17, and it extensively employs modern programming techniques. Type erasure is used pervasively throughout the codebase to provide a form of runtime polymorphism which is safer and more ergonomic than traditional object-oriented programming. Template meta-programming techniques are used for compile-time introspection, and, paired to sensible defaults, they help to reduce the amount of boilerplate needed to define new optimisation problems. pagmo is designed for extensive customisation: any element of the framework (including solvers, islands, batch fitness evaluators, archipelago topologies, migration policies, etc.) can easily be replaced with custom implementations tailored for specific needs.

Python
In order to provide an interactive mode of usage (and in order to participate in the ecosystem of what is arguably the most popular language for scientific computing today), pagmo provides a complete set of Python bindings called pygmo, implemented via pybind11 (Jakob, Rhinelander, & Moldovan, 2017). pygmo exposes all pagmo features, including the ability to implement new problems, solvers, batch evaluators, topologies etc. in pure Python, using an API which closely matches the C++ pagmo API. Additionally, pygmo offers Python-specific features, such as the ability to use ipyparallel (Ragan-Kelley, 2020) for cluster-level parallelisation, and wrappers to use optimisation algorithms from Scipy (Virtanen et al., 2020) as pygmo algorithms.

Testing and documentation
The pagmo development team places a strong emphasis on automated testing. The code is fully covered by unit tests, and the continuous integration pipeline checks that the code compiles and runs correctly on a variety of operating systems (Linux, OSX, Windows) using different compilers (GCC, Clang, MSVC). Both the C++ and Python APIs are fully documented, and as a policy we require that every PR to pagmo or pygmo must not decrease testing or documentation coverage.

Some API examples
In this section, we will show how pagmo and pygmo can be used to solve a very simple optimisation problem using the Differential Evolution (DE) algorithm (Storn & Price, 1997). The problem that we will solve is the minimisation of the unidimensional sphere function, subject to the box bounds x ∈ [0, 1]. This is, of course, a trivial problem with solution x = 0, and it is used here only for didactic purposes. In pagmo, decision vectors and problem bounds are represented via the pagmo::vector_doub le type, which is currently just an alias for std::vector<double>. The fitness function also returns a vector_double, because, generally-speaking, the fitness vector must accommodate multiple scalar values to represent multiple objectives and constraints. Here, however, the sphere_1d problem is single-objective and unconstrained, and thus the only element in the fitness vector will be the value of the objective function.

C++
In this example, 20 initial conditions for the optimisation are randomly chosen within the problem bounds when creating the pop object. It is of course possible to explicitly set the initial conditions, if so desired. The Differential Evolution algorithm object is then created, specifying 500 generations as a stopping criterion.
The initial population pop is then evolved, and the result is a new population of optimised decision vectors, new_pop. The fitness of the best decision vector (the "champion") is then printed to the screen.
sphere_1d, as an unconstrained, single-objective, continuous optimisation problem, is the simplest optimisation problem type that can be defined in pagmo. More complex problems can be defined by adding new member functions to the problem class. For instance: • by implementing the get_nec() and get_nic() member functions, the user can specify the number of, respectively, equality and inequality constraints in the problem. If, like in the case of sphere_1d, these functions are not implemented, pagmo assumes that the problem is unconstrained; • by implementing the get_nobj() member function, the user can specify the number of objectives in the optimisation problem. If this function is not implemented, pagmo assumes that the problem is single-objective.

Python
from pygmo import problem, algorithm, population, de As shown in this example, the pygmo Python API very closely follows the pagmo C++ API.

Availability
Both pagmo and pygmo are available in the conda package manager through the conda-forge community-driven channel. Additionally, the core team also maintains pip packages for Linux.
The wider pagmo user community provides also additional packages for Arch Linux, OSX (via Homebrew) and FreeBSD.