diff --git a/.github/azure-pipelines.yaml b/.github/azure-pipelines.yaml index bcce5c0d..955eabd5 100644 --- a/.github/azure-pipelines.yaml +++ b/.github/azure-pipelines.yaml @@ -18,3 +18,4 @@ extends: IMAGE: auto ISORT: true COVERAGE: true + TIMEOUT_BUILD: 30 diff --git a/pyoptsparse/pyNSGA2/pyNSGA2.py b/pyoptsparse/pyNSGA2/pyNSGA2.py index c83faa18..b7710828 100644 --- a/pyoptsparse/pyNSGA2/pyNSGA2.py +++ b/pyoptsparse/pyNSGA2/pyNSGA2.py @@ -4,6 +4,7 @@ """ # Standard Python modules +import datetime import os import time @@ -179,6 +180,12 @@ def objconfunc(nreal, nobj, ncon, x, f, g): # fmt: on optTime = time.time() - t0 + if self.storeHistory: + self.metadata["endTime"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + self.metadata["optTime"] = optTime + self.hist.writeData("metadata", self.metadata) + self.hist.close() + # Broadcast a -1 to indcate NSGA2 has finished self.optProb.comm.bcast(-1, root=0) diff --git a/pyoptsparse/testing/pyOpt_testing.py b/pyoptsparse/testing/pyOpt_testing.py index c9535e39..e6dafabf 100644 --- a/pyoptsparse/testing/pyOpt_testing.py +++ b/pyoptsparse/testing/pyOpt_testing.py @@ -274,7 +274,9 @@ def check_hist_file(self, tol): hist = History(self.histFileName, flag="r") # Metadata checks metadata = hist.getMetadata() - self.assertEqual(metadata["optimizer"], self.optName) + # NSGA2's official name is NSGA-II + if self.optName != "NSGA2": + self.assertEqual(metadata["optimizer"], self.optName) metadata_def_keys = [ "optName", "optOptions", diff --git a/tests/test_sphere.py b/tests/test_sphere.py index 34c8f0e2..b1b5e292 100644 --- a/tests/test_sphere.py +++ b/tests/test_sphere.py @@ -9,8 +9,11 @@ # First party modules from pyoptsparse import Optimization +from pyoptsparse.pyOpt_optimizer import Optimizers from pyoptsparse.testing import OptTest +ALL_OPTIMIZERS = sorted({e.name for e in Optimizers} - {"ParOpt", "NSGA2"}) + class TestSphere(OptTest): ## Solve unconstrained Sphere problem. @@ -38,7 +41,7 @@ class TestSphere(OptTest): xStar = {"xvars": np.zeros(N)} # Tolerances - tol = {"ALPSO": 1e-3} + tol = {k: 5e-2 if k in ["CONMIN", "ALPSO", "NSGA2"] else 1e-6 for k in ALL_OPTIMIZERS} optOptions = { "ALPSO": { # sphere @@ -48,7 +51,15 @@ class TestSphere(OptTest): "c2": 1.25, # Social Parameter "stopCriteria": 0, # 0: maxOuterIter, 1: convergence "seed": 1235, - } + }, + "NSGA2": { # not tested due to NSGA2 testing issues but option is kept here for reference + "PopSize": 32, + "maxGen": 100, + "seed": 123, + }, + "SNOPT": { + "Major iterations limit": 10, + }, } def objfunc(self, xdict): @@ -63,8 +74,7 @@ def objfunc(self, xdict): def sens(self, xdict, _funcs): self.ng += 1 x = xdict["xvars"] - - funcsSens = {"obj": {"xvars": 2 * np.ones(len(x))}} + funcsSens = {"obj": {"xvars": 2 * x}} fail = False return funcsSens, fail @@ -83,7 +93,7 @@ def setup_optProb(self): # Objective self.optProb.addObj("obj") - @parameterized.expand(["ALPSO"]) + @parameterized.expand(ALL_OPTIMIZERS) def test_optimization(self, optName): self.optName = optName self.setup_optProb()