From aee9adde7c80a0f89e3f1ad424d9a2e766ad47d1 Mon Sep 17 00:00:00 2001 From: mrava87 Date: Tue, 1 Jul 2025 08:37:05 +0000 Subject: [PATCH 01/13] test: fix tests not working with high nranks and change GA to test that --- .github/workflows/build.yml | 2 +- Makefile | 2 +- tests/test_distributedarray.py | 45 +++++++++++++++++++++++++++------- tests/test_fredholm.py | 12 ++++----- tests/test_solver.py | 13 +++++++++- 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4de6df86..55eecd5e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: os: [ubuntu-latest, macos-latest] python-version: ['3.10', '3.11', '3.12', '3.13'] mpi: ['mpich', 'openmpi', 'intelmpi'] - rank: ['2', '3', '4'] + rank: ['2', '4', '9'] exclude: - os: macos-latest mpi: 'intelmpi' diff --git a/Makefile b/Makefile index 7d866764..d2715edd 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PIP := $(shell command -v pip3 2> /dev/null || command which pip 2> /dev/null) PYTHON := $(shell command -v python3 2> /dev/null || command which python 2> /dev/null) -NUM_PROCESSES = 3 +NUM_PROCESSES = 4 .PHONY: install dev-install dev-install_nccl install_ \ conda install_conda_nccl dev-install_conda dev-install_conda_nccl \ diff --git a/tests/test_distributedarray.py b/tests/test_distributedarray.py index bc3d7a32..34944b06 100644 --- a/tests/test_distributedarray.py +++ b/tests/test_distributedarray.py @@ -199,12 +199,21 @@ def test_distributed_norm(par): def test_distributed_masked(par): """Test Asarray with masked array""" # Number of subcommunicators - if MPI.COMM_WORLD.Get_size() % 2 == 0: + size = MPI.COMM_WORLD.Get_size() + + # Exclude not handled cases + shape_axis = par['x'].shape[par['axis']] + print('shape_axis, size', shape_axis, size, shape_axis % size != 0) + if shape_axis % size != 0: + pytest.skip(f"Array dimension to distributed ({shape_axis}) is not " + f"divisible by the number of processes ({size})...") + if size % 2 == 0: nsub = 2 - elif MPI.COMM_WORLD.Get_size() % 3 == 0: + elif size % 3 == 0: nsub = 3 else: - pass + pytest.skip(f"Number of processes ({size}) is not divisible " + "by 2 or 3...") subsize = max(1, MPI.COMM_WORLD.Get_size() // nsub) mask = np.repeat(np.arange(nsub), subsize) @@ -236,12 +245,21 @@ def test_distributed_masked(par): def test_distributed_maskeddot(par1, par2): """Test Distributed Dot product with masked array""" # Number of subcommunicators - if MPI.COMM_WORLD.Get_size() % 2 == 0: + size = MPI.COMM_WORLD.Get_size() + + # Exclude not handled cases + shape_axis = par1['x'].shape[par1['axis']] + print('shape_axis, size', shape_axis, size, shape_axis % size != 0) + if shape_axis % size != 0: + pytest.skip(f"Array dimension to distributed ({shape_axis}) is not " + f"divisible by the number of processes ({size})...") + if size % 2 == 0: nsub = 2 - elif MPI.COMM_WORLD.Get_size() % 3 == 0: + elif size % 3 == 0: nsub = 3 else: - pass + pytest.skip(f"Number of processes ({size}) is not divisible " + "by 2 or 3...") subsize = max(1, MPI.COMM_WORLD.Get_size() // nsub) mask = np.repeat(np.arange(nsub), subsize) @@ -271,12 +289,21 @@ def test_distributed_maskeddot(par1, par2): def test_distributed_maskednorm(par): """Test Distributed numpy.linalg.norm method with masked array""" # Number of subcommunicators - if MPI.COMM_WORLD.Get_size() % 2 == 0: + size = MPI.COMM_WORLD.Get_size() + + # Exclude not handled cases + shape_axis = par['x'].shape[par['axis']] + print('shape_axis, size', shape_axis, size, shape_axis % size != 0) + if shape_axis % size != 0: + pytest.skip(f"Array dimension to distributed ({shape_axis}) is not " + f"divisible by the number of processes ({size})...") + if size % 2 == 0: nsub = 2 - elif MPI.COMM_WORLD.Get_size() % 3 == 0: + elif size % 3 == 0: nsub = 3 else: - pass + pytest.skip(f"Number of processes ({size}) is not divisible " + "by 2 or 3...") subsize = max(1, MPI.COMM_WORLD.Get_size() // nsub) mask = np.repeat(np.arange(nsub), subsize) # Replicate x as required in masked arrays diff --git a/tests/test_fredholm.py b/tests/test_fredholm.py index 3d45a4c6..95bd5468 100644 --- a/tests/test_fredholm.py +++ b/tests/test_fredholm.py @@ -20,7 +20,7 @@ size = MPI.COMM_WORLD.Get_size() par1 = { - "nsl": 12, + "nsl": 21, "ny": 6, "nx": 4, "nz": 5, @@ -30,7 +30,7 @@ "dtype": "float32", } # real, saved Gt par2 = { - "nsl": 12, + "nsl": 21, "ny": 6, "nx": 4, "nz": 5, @@ -40,7 +40,7 @@ "dtype": "float32", } # real, unsaved Gt par3 = { - "nsl": 12, + "nsl": 21, "ny": 6, "nx": 4, "nz": 5, @@ -50,7 +50,7 @@ "dtype": "complex64", } # complex, saved Gt par4 = { - "nsl": 12, + "nsl": 21, "ny": 6, "nx": 4, "nz": 5, @@ -60,7 +60,7 @@ "dtype": "complex64", } # complex, unsaved Gt par5 = { - "nsl": 12, + "nsl": 21, "ny": 6, "nx": 4, "nz": 1, @@ -70,7 +70,7 @@ "dtype": "float32", } # real, saved Gt, nz=1 par6 = { - "nsl": 12, + "nsl": 21, "ny": 6, "nx": 4, "nz": 1, diff --git a/tests/test_solver.py b/tests/test_solver.py index 46e9a139..f79e3e61 100644 --- a/tests/test_solver.py +++ b/tests/test_solver.py @@ -26,7 +26,6 @@ StackedDistributedArray ) -np.random.seed(42) size = MPI.COMM_WORLD.Get_size() rank = MPI.COMM_WORLD.Get_rank() @@ -94,6 +93,8 @@ ) def test_cg(par): """CG with MPIBlockDiag""" + np.random.seed(42) + A = np.ones((par["ny"], par["nx"])) + par[ "imag"] * np.ones((par["ny"], par["nx"])) Aop = MatrixMult(np.conj(A.T) @ A, dtype=par['dtype']) @@ -139,6 +140,8 @@ def test_cg(par): ) def test_cgls(par): """CGLS with MPIBlockDiag""" + np.random.seed(42) + A = np.ones((par["ny"], par["nx"])) + par[ "imag"] * np.ones((par["ny"], par["nx"])) Aop = MatrixMult(np.conj(A.T) @ A + 1e-5 * np.eye(par["nx"], dtype=par['dtype']), @@ -186,6 +189,8 @@ def test_cgls(par): ) def test_cgls_broadcastdata(par): """CGLS with broadcasted data vector""" + np.random.seed(42) + A = (rank + 1) * np.ones((par["ny"], par["nx"])) + (rank + 2) * par[ "imag" ] * np.ones((par["ny"], par["nx"])) @@ -232,6 +237,8 @@ def test_cgls_broadcastdata(par): ) def test_cgls_broadcastmodel(par): """CGLS with broadcasted model vector""" + np.random.seed(42) + A = np.ones((par["ny"], par["nx"])) + par[ "imag"] * np.ones((par["ny"], par["nx"])) Aop = MatrixMult(np.conj(A.T) @ A + 1e-5 * np.eye(par["nx"], dtype=par['dtype']), @@ -281,6 +288,8 @@ def test_cgls_broadcastmodel(par): ) def test_cg_stacked(par): """CG with MPIStackedBlockDiag""" + np.random.seed(42) + A = np.ones((par["ny"], par["nx"])) + par[ "imag"] * np.ones((par["ny"], par["nx"])) Aop = MatrixMult(np.conj(A.T) @ A + 1e-5 * np.eye(par["nx"], dtype=par['dtype']), @@ -344,6 +353,8 @@ def test_cg_stacked(par): ) def test_cgls_stacked(par): """CGLS with MPIStackedBlockDiag""" + np.random.seed(42) + A = np.ones((par["ny"], par["nx"])) + par[ "imag"] * np.ones((par["ny"], par["nx"])) Aop = MatrixMult(np.conj(A.T) @ A + 1e-5 * np.eye(par["nx"], dtype=par['dtype']), From 12d17082c16c3b30fecec17bae6584fe3878cdf4 Mon Sep 17 00:00:00 2001 From: mrava87 Date: Wed, 2 Jul 2025 22:05:56 +0000 Subject: [PATCH 02/13] ci: exclude rank=9 for openmpi as it does not run in CI (works locally) --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55eecd5e..cb6b2ada 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,6 +20,8 @@ jobs: exclude: - os: macos-latest mpi: 'intelmpi' + - mpi: 'openmpi' + rank: '9' # works locally, not in CI runs-on: ${{ matrix.os }} steps: - name: Checkout From c496bedc8268184e24e4554383a87a7a7867f695 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 20:28:36 +0530 Subject: [PATCH 03/13] Add --oversubscribe for openmpi tests --- .github/workflows/build.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb6b2ada..53fcc0e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,8 +20,6 @@ jobs: exclude: - os: macos-latest mpi: 'intelmpi' - - mpi: 'openmpi' - rank: '9' # works locally, not in CI runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -45,4 +43,9 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi + run: | + if [ "${{ matrix.mpi }}" = "openmpi" ]; then + mpiexec --oversubscribe -n ${{ matrix.rank }} pytest tests/ --with-mpi + else + mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi + fi From ece73240db96a5d8d22b00926e3d9ad43f6dd9d6 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 20:42:58 +0530 Subject: [PATCH 04/13] Minor test by adding --host --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 53fcc0e9..d04eb950 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: - name: Testing using pytest-mpi run: | if [ "${{ matrix.mpi }}" = "openmpi" ]; then - mpiexec --oversubscribe -n ${{ matrix.rank }} pytest tests/ --with-mpi + mpiexec --oversubscribe -n ${{ matrix.rank }} --host localhost:${{ matrix.rank }} pytest tests/ --with-mpi else mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi fi From f86a352469656f7a136187f093ec28b45c09bf95 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 22:23:17 +0530 Subject: [PATCH 05/13] Check on test solver --- .github/workflows/build.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d04eb950..e23035c6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,9 +43,4 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: | - if [ "${{ matrix.mpi }}" = "openmpi" ]; then - mpiexec --oversubscribe -n ${{ matrix.rank }} --host localhost:${{ matrix.rank }} pytest tests/ --with-mpi - else - mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi - fi + run: mpiexec -n ${{ matrix.rank }} pytest tests/test_solver.py --with-mpi From 2127a902bfb42ba947428217b1eef0ffcda3566b Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 22:38:57 +0530 Subject: [PATCH 06/13] Update command to test --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e23035c6..fda99bbe 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,4 +43,4 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: mpiexec -n ${{ matrix.rank }} pytest tests/test_solver.py --with-mpi + run: mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi -v -x From 628049fd9f19cb964fca3cc99dba50b1a8679685 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 22:43:22 +0530 Subject: [PATCH 07/13] Testing only test_blockdiag --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fda99bbe..9e0684ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,4 +43,4 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi -v -x + run: mpiexec -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x From 206d7bef243c7c44df527a57fd1423385ec10ef7 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 22:49:47 +0530 Subject: [PATCH 08/13] Commenting stacked blockdiag --- .github/workflows/build.yml | 2 +- tests/test_blockdiag.py | 92 ++++++++++++++++++------------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e0684ec..fda99bbe 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,4 +43,4 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: mpiexec -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + run: mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi -v -x diff --git a/tests/test_blockdiag.py b/tests/test_blockdiag.py index bd6b81a5..dfaddb2a 100644 --- a/tests/test_blockdiag.py +++ b/tests/test_blockdiag.py @@ -57,49 +57,49 @@ def test_blockdiag(par): assert_allclose(y_rmat_mpi, y_rmat_np, rtol=1e-14) -@pytest.mark.mpi(min_size=2) -@pytest.mark.parametrize("par", [(par1), (par1j), (par2), (par2j)]) -def test_stacked_blockdiag(par): - """Tests for MPIStackedBlogDiag""" - size = MPI.COMM_WORLD.Get_size() - rank = MPI.COMM_WORLD.Get_rank() - Op = pylops.MatrixMult(A=((rank + 1) * np.ones(shape=(par['ny'], par['nx']))).astype(par['dtype'])) - BDiag_MPI = pylops_mpi.MPIBlockDiag(ops=[Op, ]) - FirstDeriv_MPI = pylops_mpi.MPIFirstDerivative(dims=(par['ny'], par['nx']), dtype=par['dtype']) - StackedBDiag_MPI = pylops_mpi.MPIStackedBlockDiag(ops=[BDiag_MPI, FirstDeriv_MPI]) - - dist1 = pylops_mpi.DistributedArray(global_shape=size * par['nx'], dtype=par['dtype']) - dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) - dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) - dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) - x = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) - x_global = x.asarray() - - dist1 = pylops_mpi.DistributedArray(global_shape=size * par['ny'], dtype=par['dtype']) - dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) - dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) - dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) - y = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) - y_global = y.asarray() - - # Forward - x_mat = StackedBDiag_MPI @ x - # Adjoint - y_rmat = StackedBDiag_MPI.H @ y - assert isinstance(x_mat, pylops_mpi.StackedDistributedArray) - assert isinstance(y_rmat, pylops_mpi.StackedDistributedArray) - # Dot test - dottest(StackedBDiag_MPI, x, y, size * par['ny'] + par['nx'] * par['ny'], size * par['nx'] + par['nx'] * par['ny']) - - x_mat_mpi = x_mat.asarray() - y_rmat_mpi = y_rmat.asarray() - - if rank == 0: - ops = [pylops.MatrixMult((i + 1) * np.ones(shape=(par['ny'], par['nx'])).astype(par['dtype'])) for i in range(size)] - BDiag = pylops.BlockDiag(ops=ops) - FirstDeriv = pylops.FirstDerivative(dims=(par['ny'], par['nx']), axis=0, dtype=par['dtype']) - BDiag_final = pylops.BlockDiag([BDiag, FirstDeriv]) - x_mat_np = BDiag_final @ x_global - y_rmat_np = BDiag_final.H @ y_global - assert_allclose(x_mat_mpi, x_mat_np, rtol=1e-14) - assert_allclose(y_rmat_mpi, y_rmat_np, rtol=1e-14) +# @pytest.mark.mpi(min_size=2) +# @pytest.mark.parametrize("par", [(par1), (par1j), (par2), (par2j)]) +# def test_stacked_blockdiag(par): +# """Tests for MPIStackedBlogDiag""" +# size = MPI.COMM_WORLD.Get_size() +# rank = MPI.COMM_WORLD.Get_rank() +# Op = pylops.MatrixMult(A=((rank + 1) * np.ones(shape=(par['ny'], par['nx']))).astype(par['dtype'])) +# BDiag_MPI = pylops_mpi.MPIBlockDiag(ops=[Op, ]) +# FirstDeriv_MPI = pylops_mpi.MPIFirstDerivative(dims=(par['ny'], par['nx']), dtype=par['dtype']) +# StackedBDiag_MPI = pylops_mpi.MPIStackedBlockDiag(ops=[BDiag_MPI, FirstDeriv_MPI]) +# +# dist1 = pylops_mpi.DistributedArray(global_shape=size * par['nx'], dtype=par['dtype']) +# dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) +# dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) +# dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) +# x = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) +# x_global = x.asarray() +# +# dist1 = pylops_mpi.DistributedArray(global_shape=size * par['ny'], dtype=par['dtype']) +# dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) +# dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) +# dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) +# y = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) +# y_global = y.asarray() +# +# # Forward +# x_mat = StackedBDiag_MPI @ x +# # Adjoint +# y_rmat = StackedBDiag_MPI.H @ y +# assert isinstance(x_mat, pylops_mpi.StackedDistributedArray) +# assert isinstance(y_rmat, pylops_mpi.StackedDistributedArray) +# # Dot test +# dottest(StackedBDiag_MPI, x, y, size * par['ny'] + par['nx'] * par['ny'], size * par['nx'] + par['nx'] * par['ny']) +# +# x_mat_mpi = x_mat.asarray() +# y_rmat_mpi = y_rmat.asarray() +# +# if rank == 0: +# ops = [pylops.MatrixMult((i + 1) * np.ones(shape=(par['ny'], par['nx'])).astype(par['dtype'])) for i in range(size)] +# BDiag = pylops.BlockDiag(ops=ops) +# FirstDeriv = pylops.FirstDerivative(dims=(par['ny'], par['nx']), axis=0, dtype=par['dtype']) +# BDiag_final = pylops.BlockDiag([BDiag, FirstDeriv]) +# x_mat_np = BDiag_final @ x_global +# y_rmat_np = BDiag_final.H @ y_global +# assert_allclose(x_mat_mpi, x_mat_np, rtol=1e-14) +# assert_allclose(y_rmat_mpi, y_rmat_np, rtol=1e-14) From 5656aba40cc0f967757b383ac04f7d0649d818cc Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 23:00:55 +0530 Subject: [PATCH 09/13] Check for smaller values --- .github/workflows/build.yml | 2 +- tests/test_blockdiag.py | 100 ++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fda99bbe..9e0684ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,4 +43,4 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi -v -x + run: mpiexec -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x diff --git a/tests/test_blockdiag.py b/tests/test_blockdiag.py index dfaddb2a..23e53f10 100644 --- a/tests/test_blockdiag.py +++ b/tests/test_blockdiag.py @@ -11,10 +11,10 @@ import pylops_mpi from pylops_mpi.utils.dottest import dottest -par1 = {'ny': 101, 'nx': 101, 'dtype': np.float64} -par1j = {'ny': 101, 'nx': 101, 'dtype': np.complex128} -par2 = {'ny': 301, 'nx': 101, 'dtype': np.float64} -par2j = {'ny': 301, 'nx': 101, 'dtype': np.complex128} +par1 = {'ny': 31, 'nx': 31, 'dtype': np.float64} +par1j = {'ny': 41, 'nx': 41, 'dtype': np.complex128} +par2 = {'ny': 31, 'nx': 41, 'dtype': np.float64} +par2j = {'ny': 31, 'nx': 41, 'dtype': np.complex128} np.random.seed(42) @@ -57,49 +57,49 @@ def test_blockdiag(par): assert_allclose(y_rmat_mpi, y_rmat_np, rtol=1e-14) -# @pytest.mark.mpi(min_size=2) -# @pytest.mark.parametrize("par", [(par1), (par1j), (par2), (par2j)]) -# def test_stacked_blockdiag(par): -# """Tests for MPIStackedBlogDiag""" -# size = MPI.COMM_WORLD.Get_size() -# rank = MPI.COMM_WORLD.Get_rank() -# Op = pylops.MatrixMult(A=((rank + 1) * np.ones(shape=(par['ny'], par['nx']))).astype(par['dtype'])) -# BDiag_MPI = pylops_mpi.MPIBlockDiag(ops=[Op, ]) -# FirstDeriv_MPI = pylops_mpi.MPIFirstDerivative(dims=(par['ny'], par['nx']), dtype=par['dtype']) -# StackedBDiag_MPI = pylops_mpi.MPIStackedBlockDiag(ops=[BDiag_MPI, FirstDeriv_MPI]) -# -# dist1 = pylops_mpi.DistributedArray(global_shape=size * par['nx'], dtype=par['dtype']) -# dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) -# dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) -# dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) -# x = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) -# x_global = x.asarray() -# -# dist1 = pylops_mpi.DistributedArray(global_shape=size * par['ny'], dtype=par['dtype']) -# dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) -# dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) -# dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) -# y = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) -# y_global = y.asarray() -# -# # Forward -# x_mat = StackedBDiag_MPI @ x -# # Adjoint -# y_rmat = StackedBDiag_MPI.H @ y -# assert isinstance(x_mat, pylops_mpi.StackedDistributedArray) -# assert isinstance(y_rmat, pylops_mpi.StackedDistributedArray) -# # Dot test -# dottest(StackedBDiag_MPI, x, y, size * par['ny'] + par['nx'] * par['ny'], size * par['nx'] + par['nx'] * par['ny']) -# -# x_mat_mpi = x_mat.asarray() -# y_rmat_mpi = y_rmat.asarray() -# -# if rank == 0: -# ops = [pylops.MatrixMult((i + 1) * np.ones(shape=(par['ny'], par['nx'])).astype(par['dtype'])) for i in range(size)] -# BDiag = pylops.BlockDiag(ops=ops) -# FirstDeriv = pylops.FirstDerivative(dims=(par['ny'], par['nx']), axis=0, dtype=par['dtype']) -# BDiag_final = pylops.BlockDiag([BDiag, FirstDeriv]) -# x_mat_np = BDiag_final @ x_global -# y_rmat_np = BDiag_final.H @ y_global -# assert_allclose(x_mat_mpi, x_mat_np, rtol=1e-14) -# assert_allclose(y_rmat_mpi, y_rmat_np, rtol=1e-14) +@pytest.mark.mpi(min_size=2) +@pytest.mark.parametrize("par", [(par1), (par1j), (par2), (par2j)]) +def test_stacked_blockdiag(par): + """Tests for MPIStackedBlogDiag""" + size = MPI.COMM_WORLD.Get_size() + rank = MPI.COMM_WORLD.Get_rank() + Op = pylops.MatrixMult(A=((rank + 1) * np.ones(shape=(par['ny'], par['nx']))).astype(par['dtype'])) + BDiag_MPI = pylops_mpi.MPIBlockDiag(ops=[Op, ]) + FirstDeriv_MPI = pylops_mpi.MPIFirstDerivative(dims=(par['ny'], par['nx']), dtype=par['dtype']) + StackedBDiag_MPI = pylops_mpi.MPIStackedBlockDiag(ops=[BDiag_MPI, FirstDeriv_MPI]) + + dist1 = pylops_mpi.DistributedArray(global_shape=size * par['nx'], dtype=par['dtype']) + dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) + dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) + dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) + x = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) + x_global = x.asarray() + + dist1 = pylops_mpi.DistributedArray(global_shape=size * par['ny'], dtype=par['dtype']) + dist1[:] = np.ones(dist1.local_shape, dtype=par['dtype']) + dist2 = pylops_mpi.DistributedArray(global_shape=par['nx'] * par['ny'], dtype=par['dtype']) + dist2[:] = np.ones(dist2.local_shape, dtype=par['dtype']) + y = pylops_mpi.StackedDistributedArray(distarrays=[dist1, dist2]) + y_global = y.asarray() + + # Forward + x_mat = StackedBDiag_MPI @ x + # Adjoint + y_rmat = StackedBDiag_MPI.H @ y + assert isinstance(x_mat, pylops_mpi.StackedDistributedArray) + assert isinstance(y_rmat, pylops_mpi.StackedDistributedArray) + # Dot test + dottest(StackedBDiag_MPI, x, y, size * par['ny'] + par['nx'] * par['ny'], size * par['nx'] + par['nx'] * par['ny']) + + x_mat_mpi = x_mat.asarray() + y_rmat_mpi = y_rmat.asarray() + + if rank == 0: + ops = [pylops.MatrixMult((i + 1) * np.ones(shape=(par['ny'], par['nx'])).astype(par['dtype'])) for i in range(size)] + BDiag = pylops.BlockDiag(ops=ops) + FirstDeriv = pylops.FirstDerivative(dims=(par['ny'], par['nx']), axis=0, dtype=par['dtype']) + BDiag_final = pylops.BlockDiag([BDiag, FirstDeriv]) + x_mat_np = BDiag_final @ x_global + y_rmat_np = BDiag_final.H @ y_global + assert_allclose(x_mat_mpi, x_mat_np, rtol=1e-14) + assert_allclose(y_rmat_mpi, y_rmat_np, rtol=1e-14) From a1952cca99d949bac129d571c01f1c77d7c17ab5 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 23:09:30 +0530 Subject: [PATCH 10/13] Update add --host --- .github/workflows/build.yml | 2 +- tests/test_blockdiag.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e0684ec..f52c08e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,4 +43,4 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: mpiexec -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + run: mpiexec --host localhost:12 -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x diff --git a/tests/test_blockdiag.py b/tests/test_blockdiag.py index 23e53f10..bd6b81a5 100644 --- a/tests/test_blockdiag.py +++ b/tests/test_blockdiag.py @@ -11,10 +11,10 @@ import pylops_mpi from pylops_mpi.utils.dottest import dottest -par1 = {'ny': 31, 'nx': 31, 'dtype': np.float64} -par1j = {'ny': 41, 'nx': 41, 'dtype': np.complex128} -par2 = {'ny': 31, 'nx': 41, 'dtype': np.float64} -par2j = {'ny': 31, 'nx': 41, 'dtype': np.complex128} +par1 = {'ny': 101, 'nx': 101, 'dtype': np.float64} +par1j = {'ny': 101, 'nx': 101, 'dtype': np.complex128} +par2 = {'ny': 301, 'nx': 101, 'dtype': np.float64} +par2j = {'ny': 301, 'nx': 101, 'dtype': np.complex128} np.random.seed(42) From 7d970f424a4aa4fa006e88d5aa72faf59bafd854 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 23:12:40 +0530 Subject: [PATCH 11/13] Update add --host --- .github/workflows/build.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f52c08e1..76e24866 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,4 +43,9 @@ jobs: - name: Install pylops-mpi run: pip install . - name: Testing using pytest-mpi - run: mpiexec --host localhost:12 -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + run: | + if [ "${{ matrix.mpi }}" = "openmpi" ]; then + mpiexec --host localhost:12 -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + else + mpiexec -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + fi From 5cfec9f87f7de597449b451aee210438abe71c4d Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 23:22:28 +0530 Subject: [PATCH 12/13] Minor check to see if oversubscribing and non-binding works --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 76e24866..9b726ddf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: - name: Testing using pytest-mpi run: | if [ "${{ matrix.mpi }}" = "openmpi" ]; then - mpiexec --host localhost:12 -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + mpiexec --oversubscribe --mca btl ^openib --bind-to none -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x else mpiexec -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x fi From e10c97f8bddaf2047426e90b674934609bab9911 Mon Sep 17 00:00:00 2001 From: rohanbabbar04 Date: Sat, 12 Jul 2025 23:39:26 +0530 Subject: [PATCH 13/13] Test for tests/ --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b726ddf..05d503fa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: - name: Testing using pytest-mpi run: | if [ "${{ matrix.mpi }}" = "openmpi" ]; then - mpiexec --oversubscribe --mca btl ^openib --bind-to none -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + mpiexec --oversubscribe --mca btl ^openib --bind-to none -n ${{ matrix.rank }} pytest tests/ --with-mpi else - mpiexec -n ${{ matrix.rank }} pytest tests/test_blockdiag.py --with-mpi -v -x + mpiexec -n ${{ matrix.rank }} pytest tests/ --with-mpi fi