MPI example gets stuck
SanPen opened this issue · comments
Hi, I am trying the examples provided and the MPI example gets stuck, not error, just not advancing nor calling the objective function. I have tried the same code under windows 10 (after installing MPI from microsoft) and under Ubuntu 18.
I wonder is this is a bug, of if I am missing something.
The code is this:
"""
.. module:: mpiexample_simple_mpi
:synopsis: Simple MPI example
.. moduleauthor:: David Eriksson <dme65@cornell.edu>
"""
from pySOT.experimental_design import SymmetricLatinHypercube
from pySOT.strategy import SRBFStrategy
from pySOT.surrogate import RBFInterpolant, CubicKernel, LinearTail
from pySOT.optimization_problems import OptimizationProblem
from poap.mpiserve import MPIController, MPISimpleWorker
import numpy as np
import os.path
import logging
# Try to import mpi4py
try:
from mpi4py import MPI
except Exception as err:
print("ERROR: You need mpi4py to use the POAP MPI controller.")
exit()
class Ackley(OptimizationProblem):
"""
Ackley function
.. math::
f(x_1,\\ldots,x_n) = -20\\exp\\left( -0.2 \\sqrt{\\frac{1}{n} \
\\sum_{j=1}^n x_j^2} \\right) -\\exp \\left( \\frac{1}{n} \
\\sum{j=1}^n \\cos(2 \\pi x_j) \\right) + 20 - e
subject to
.. math::
-15 \\leq x_i \\leq 20
Global optimum: :math:`f(0,0,...,0)=0`
:ivar dim: Number of dimensions
:ivar lb: Lower variable bounds
:ivar ub: Upper variable bounds
:ivar int_var: Integer variables
:ivar cont_var: Continuous variables
:ivar min: Global minimum value
:ivar minimum: Global minimizer
:ivar info: String with problem info
"""
def __init__(self, dim=10):
self.dim = dim
self.min = 0
self.minimum = np.zeros(dim)
self.lb = -15 * np.ones(dim)
self.ub = 20 * np.ones(dim)
self.int_var = np.array([])
self.cont_var = np.arange(0, dim)
self.info = str(dim) + "-dimensional Ackley function \n" + "Global optimum: f(0,0,...,0) = 0"
def eval(self, x):
"""
Evaluate the Ackley function at x
:param x: Data point
:type x: numpy.array
:return: Value at x
:rtype: float
"""
print('eval!')
self.__check_input__(x)
d = float(self.dim)
return -20.0 * np.exp(-0.2*np.sqrt(np.sum(x**2) / d)) - np.exp(np.sum(np.cos(2.0*np.pi*x)) / d) + 20 + np.exp(1)
def main_worker(objfunction):
MPISimpleWorker(objfunction).run()
def main_master(opt_prob, num_workers):
if not os.path.exists("./logfiles"):
os.makedirs("logfiles")
if os.path.exists("./logfiles/mpiexample_mpi.log"):
os.remove("./logfiles/mpiexample_mpi.log")
logging.basicConfig(filename="./logfiles/mpiexample_mpi.log",
level=logging.INFO)
max_evals = 500
rbf = RBFInterpolant(dim=opt_prob.dim,
kernel=CubicKernel(),
tail=LinearTail(opt_prob.dim))
slhd = SymmetricLatinHypercube(dim=opt_prob.dim,
num_pts=2*(opt_prob.dim+1))
# Create a strategy and a controller
strategy = SRBFStrategy(max_evals=max_evals,
opt_prob=opt_prob,
exp_design=slhd,
surrogate=rbf,
asynchronous=True,
batch_size=num_workers)
controller = MPIController(strategy)
print("Number of workers: {}".format(num_workers))
print("Maximum number of evaluations: {}".format(max_evals))
print("Strategy: {}".format(controller.strategy.__class__.__name__))
print("Experimental design: {}".format(slhd.__class__.__name__))
print("Surrogate: {}".format(rbf.__class__.__name__))
print('Running...')
result = controller.run()
print('Best value found: {0}'.format(result.value))
print('Best solution found: {0}\n'.format(np.array_str(result.params[0],
max_line_width=np.inf,
precision=5,
suppress_small=True)))
def mpi_example_simple():
# Optimization problem
ackley = Ackley(dim=10)
# Extract the rank
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
nprocs = comm.Get_size()
if rank == 0:
main_master(ackley, nprocs)
else:
main_worker(ackley.eval)
if __name__ == '__main__':
mpi_example_simple()
Do you have a working MPI distribution and are you making the call using mpiexec? The following seems to work fine for me:
mpiexec -n 5 python3 mpiexample_simple_mpi.py
By calling it like that it works!
However, is there another way to call the program?
I'd use this as part of a library that is used in a PyQt GUI application.
I don't know if that is possible. In any case, this question is about mpi4py
and not pySOT
, so I'm closing for now.