From 392ddb1b55334bf2e2c0917c1ff1f0bfd7f12a77 Mon Sep 17 00:00:00 2001 From: Eirikur Jonsson Date: Mon, 19 Jun 2023 15:43:37 +0000 Subject: [PATCH 1/6] fix allocation bugs for 64 bit systems --- pyoptsparse/pyNSGA2/source/allocate.c | 2 +- pyoptsparse/pyNSGA2/source/crowddist.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyoptsparse/pyNSGA2/source/allocate.c b/pyoptsparse/pyNSGA2/source/allocate.c index 271d9069d..993bfe056 100644 --- a/pyoptsparse/pyNSGA2/source/allocate.c +++ b/pyoptsparse/pyNSGA2/source/allocate.c @@ -30,7 +30,7 @@ void allocate_memory_ind (individual *ind, Global global) if (global.nbin != 0) { ind->xbin = (double *)malloc(global.nbin*sizeof(double)); - ind->gene = (int **)malloc(global.nbin*sizeof(int)); + ind->gene = (int **)malloc(global.nbin*sizeof(int *)); for (j=0; jgene[j] = (int *)malloc(global.nbits[j]*sizeof(int)); diff --git a/pyoptsparse/pyNSGA2/source/crowddist.c b/pyoptsparse/pyNSGA2/source/crowddist.c index 4b33b4cc1..7332216b4 100644 --- a/pyoptsparse/pyNSGA2/source/crowddist.c +++ b/pyoptsparse/pyNSGA2/source/crowddist.c @@ -26,7 +26,7 @@ void assign_crowding_distance_list (population *pop, list *lst, int front_size, pop->ind[lst->child->index].crowd_dist = INF; return; } - obj_array = (int **)malloc(global.nobj*sizeof(int)); + obj_array = (int **)malloc(global.nobj*sizeof(int *)); dist = (int *)malloc(front_size*sizeof(int)); for (i=0; iind[c2].crowd_dist = INF; return; } - obj_array = (int **)malloc(global.nobj*sizeof(int)); + obj_array = (int **)malloc(global.nobj*sizeof(int *)); dist = (int *)malloc(front_size*sizeof(int)); for (i=0; i Date: Thu, 17 Apr 2025 09:40:31 -0700 Subject: [PATCH 2/6] enable flaky nsga2 test --- tests/test_nsga2_multi_objective.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_nsga2_multi_objective.py b/tests/test_nsga2_multi_objective.py index 5d9f2b7eb..a6578d9cb 100644 --- a/tests/test_nsga2_multi_objective.py +++ b/tests/test_nsga2_multi_objective.py @@ -52,7 +52,7 @@ def setup_optProb(self, n_obj): @parameterized.expand( [ (1,), - # (2,), # skipping flaky multi-objective test + (2,), ] ) def test_opt(self, n_obj): From 57c6256f403d68db1cafe1f75f260094b1001061 Mon Sep 17 00:00:00 2001 From: Ella Wu <602725+ewu63@users.noreply.github.com> Date: Sun, 20 Apr 2025 12:37:04 -0700 Subject: [PATCH 3/6] ensure array access is not out of bounds --- pyoptsparse/pyNSGA2/source/tourselect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyoptsparse/pyNSGA2/source/tourselect.c b/pyoptsparse/pyNSGA2/source/tourselect.c index 3d8ef8aaa..169663383 100644 --- a/pyoptsparse/pyNSGA2/source/tourselect.c +++ b/pyoptsparse/pyNSGA2/source/tourselect.c @@ -32,7 +32,7 @@ void selection (population *old_pop, population *new_pop, Global global, int *nr a2[rand] = a2[i]; a2[i] = temp; } - for (i=0; iind[a1[i]], &old_pop->ind[a1[i+1]], global); parent2 = tournament (&old_pop->ind[a1[i+2]], &old_pop->ind[a1[i+3]], global); From 2561d61f21a75a40f5f518689282241514cec5f5 Mon Sep 17 00:00:00 2001 From: Ella Wu <602725+ewu63@users.noreply.github.com> Date: Sun, 20 Apr 2025 14:29:35 -0700 Subject: [PATCH 4/6] run tests in isolation --- .github/test_real.sh | 2 +- .github/workflows/linux-build.yml | 2 +- .github/workflows/windows-build.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/test_real.sh b/.github/test_real.sh index 4af0258e2..d624a7459 100755 --- a/.github/test_real.sh +++ b/.github/test_real.sh @@ -11,4 +11,4 @@ cd tests # we have to copy over the coveragerc file to make sure it's in the # same directory where codecov is run cp ../.coveragerc . -testflo --pre_announce --disallow_deprecations -v --coverage --coverpkg pyoptsparse $EXTRA_FLAGS +testflo -i --pre_announce --disallow_deprecations -v --coverage --coverpkg pyoptsparse $EXTRA_FLAGS diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 0e4e28295..ba4f70a65 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -31,4 +31,4 @@ jobs: - name: Run tests run: | cd tests - testflo --pre_announce -v -n 1 . + testflo -i --pre_announce -v -n 1 . diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 440fee202..54b3e1093 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -52,4 +52,4 @@ jobs: run: | conda activate pyos-build cd tests - testflo --pre_announce -v -n 1 . + testflo -i --pre_announce -v -n 1 . From 9a120d3f3b4f9439c050712dd1502c8e1bf162c8 Mon Sep 17 00:00:00 2001 From: Eirikur Jonsson Date: Thu, 24 Apr 2025 16:02:55 +0000 Subject: [PATCH 5/6] enforce popsize in increments of 4 --- pyoptsparse/pyNSGA2/pyNSGA2.py | 3 +++ pyoptsparse/pyNSGA2/source/tourselect.c | 2 +- tests/test_nsga2_multi_objective.py | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pyoptsparse/pyNSGA2/pyNSGA2.py b/pyoptsparse/pyNSGA2/pyNSGA2.py index 8bd340ed0..12a0d5987 100644 --- a/pyoptsparse/pyNSGA2/pyNSGA2.py +++ b/pyoptsparse/pyNSGA2/pyNSGA2.py @@ -34,6 +34,9 @@ def __init__(self, raiseError=True, options={}): if isinstance(nsga2, str) and raiseError: raise ImportError(nsga2) + if self.getOption("PopSize") % 4 != 0: + raise ValueError("Option 'PopSize' must be a multiple of 4") + @staticmethod def _getInforms(): informs = {} diff --git a/pyoptsparse/pyNSGA2/source/tourselect.c b/pyoptsparse/pyNSGA2/source/tourselect.c index 169663383..3d8ef8aaa 100644 --- a/pyoptsparse/pyNSGA2/source/tourselect.c +++ b/pyoptsparse/pyNSGA2/source/tourselect.c @@ -32,7 +32,7 @@ void selection (population *old_pop, population *new_pop, Global global, int *nr a2[rand] = a2[i]; a2[i] = temp; } - for (i=0; iind[a1[i]], &old_pop->ind[a1[i+1]], global); parent2 = tournament (&old_pop->ind[a1[i+2]], &old_pop->ind[a1[i+3]], global); diff --git a/tests/test_nsga2_multi_objective.py b/tests/test_nsga2_multi_objective.py index a6578d9cb..d4f7bfb45 100644 --- a/tests/test_nsga2_multi_objective.py +++ b/tests/test_nsga2_multi_objective.py @@ -73,6 +73,13 @@ def test_opt(self, n_obj): assert_allclose(sol.fStar["obj1"], 12.0, atol=tol, rtol=tol) assert_allclose(sol.fStar["obj2"], 0.0, atol=tol, rtol=tol) + def test_options(self): + with self.assertRaises(ValueError): + # PopSize must be a multiple of 4 + self.setup_optProb(1) + optOptions = {"PopSize": 5} + sol = self.optimize(optOptions=optOptions) + if __name__ == "__main__": unittest.main() From 2459911403c070a0566049f81a1780e788107414 Mon Sep 17 00:00:00 2001 From: Eirikur Jonsson Date: Thu, 24 Apr 2025 16:40:09 +0000 Subject: [PATCH 6/6] flake8 --- tests/test_nsga2_multi_objective.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_nsga2_multi_objective.py b/tests/test_nsga2_multi_objective.py index d4f7bfb45..b74bab019 100644 --- a/tests/test_nsga2_multi_objective.py +++ b/tests/test_nsga2_multi_objective.py @@ -78,7 +78,7 @@ def test_options(self): # PopSize must be a multiple of 4 self.setup_optProb(1) optOptions = {"PopSize": 5} - sol = self.optimize(optOptions=optOptions) + self.optimize(optOptions=optOptions) if __name__ == "__main__":