From 8c16db0b381aa5cb1a57cea60a78b7f06884bc80 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 15:41:49 -0500 Subject: [PATCH 01/18] Use a saner install of open coarrays on github actions --- .github/workflows/CI.yml | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 82db39a9..577d5b6a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -9,6 +9,7 @@ jobs: env: FC: gfortran GCC_V: 13 + OC_V: 2.10.2 steps: - name: Checkout code @@ -29,19 +30,35 @@ jobs: id: cache-opencoarrays uses: actions/cache@v3 with: - path: "OpenCoarrays-2.10.1/" + path: "${HOME}/app/OpenCoarrays/${OC_V}/" key: ${{ steps.time.outputs.time }} - - name: Install GFortran, OpenCoarrays + - name: Install GFortran run: | sudo apt update - sudo apt install -y build-essential gfortran-${GCC_V} g++-${GCC_V} pkg-config make + sudo apt install -y build-essential gfortran-${GCC_V} g++-${GCC_V} cmake sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \ --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \ --slave /usr/bin/g++ g++ /usr/bin/g++-${GCC_V} - if [ ! -d OpenCoarrays-2.10.1 ] ; then wget -P . https://github.com/sourceryinstitute/OpenCoarrays/releases/download/2.10.1/OpenCoarrays-2.10.1.tar.gz && tar -xf OpenCoarrays-2.10.1.tar.gz && cd OpenCoarrays-2.10.1 && TERM=xterm ./install.sh -y; fi + + - name: Maybe install opencoarrays + if: steps.cache-opencoarrays.outputs.cache-hit != 'true' + run: | + wget https://github.com/sourceryinstitute/OpenCoarrays/releases/download/${OC_V}/OpenCoarrays-${OC_V}.tar.gz + tar xzvf OpenCoarrays-${OC_V}.tar.gz + cd OpenCoarrays-${OC_V} + mkdir -p "${HOME}/apps" + cmake -S . -B build -DCMAKE_INSTALL_PREFIX="${HOME}/apps/OpenCoarrays" + cmake --build build -j + cmake --build build -t install -j + cd .. + echo "${HOME}/apps/OpenCoarrays/bin" >> $GITHUB_PATH - name: Build, run, and test run: | - source OpenCoarrays-2.10.1/prerequisites/installations/opencoarrays/2.10.1/setup.sh - fpm test --compiler caf --runner "cafrun -n 2" + source OpenCoarrays-${OC_V}/prerequisites/installations/opencoarrays/${OC_V}/setup.sh + caf --show + cafrun --show + export FPM_FC=caf + fpm build || fpm build --verbose + fpm test --runner "cafrun -n 2" || fpm test --runner "cafrun -n 2" --verbose From ef43a22756cefdec6d21c23dd45352162977c52e Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 15:43:44 -0500 Subject: [PATCH 02/18] CI: fix missing mpich --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 577d5b6a..a5d1855a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -36,7 +36,7 @@ jobs: - name: Install GFortran run: | sudo apt update - sudo apt install -y build-essential gfortran-${GCC_V} g++-${GCC_V} cmake + sudo apt install -y build-essential gfortran-${GCC_V} g++-${GCC_V} cmake mpich sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \ --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \ --slave /usr/bin/g++ g++ /usr/bin/g++-${GCC_V} From 82d29328d29431a8244c8f2f6d7b9f63884650fb Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 15:57:52 -0500 Subject: [PATCH 03/18] ci: update actions and fix goof --- .github/workflows/CI.yml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a5d1855a..7b767e3c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,25 +13,19 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install fpm - uses: fortran-lang/setup-fpm@v4 + uses: fortran-lang/setup-fpm@v5 with: github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Get Time - id: time - uses: nanzm/get-time-action@v1.1 - with: - format: 'YYYY-MM' - - name: Setup cache for opencoarrays id: cache-opencoarrays - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: "${HOME}/app/OpenCoarrays/${OC_V}/" - key: ${{ steps.time.outputs.time }} + key: OC-${{ env.OC_V }} - name: Install GFortran run: | @@ -53,12 +47,11 @@ jobs: cmake --build build -t install -j cd .. echo "${HOME}/apps/OpenCoarrays/bin" >> $GITHUB_PATH + caf --show + cafrun --show - name: Build, run, and test run: | - source OpenCoarrays-${OC_V}/prerequisites/installations/opencoarrays/${OC_V}/setup.sh - caf --show - cafrun --show export FPM_FC=caf fpm build || fpm build --verbose fpm test --runner "cafrun -n 2" || fpm test --runner "cafrun -n 2" --verbose From b57530b66d6e7e0b8fd3d87863d35484f1e17576 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 16:26:40 -0500 Subject: [PATCH 04/18] ci: Fix bad path --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7b767e3c..edab46cb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -47,11 +47,11 @@ jobs: cmake --build build -t install -j cd .. echo "${HOME}/apps/OpenCoarrays/bin" >> $GITHUB_PATH - caf --show - cafrun --show - name: Build, run, and test run: | + caf --show + cafrun --show export FPM_FC=caf fpm build || fpm build --verbose fpm test --runner "cafrun -n 2" || fpm test --runner "cafrun -n 2" --verbose From eed5d841c8460f8998e8efebd82f2aa69efc7bae Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 20:34:54 -0500 Subject: [PATCH 05/18] tests: Clarify some logic in the commandline test The commandline test invokes fpm upon execution. It also was not commented to document why it does what it does and the caveats of the approach. Comments were added, along with some logic to sanitize the environment when re-running FPM. (You cannot spawn an MPI process from another MPI process, AFAIK, which is why failures are encountered if you try to run the example code stand alone application if it was built with caf.) The sanitization checks if FPM_FC is set in the environment and removes it before calling FPM to run the example code. If it were present it would run the version of the example built with caf and error out. By removing FPM_FC from the environment you ensure that a serial version is built and run. --- test/command_line_test.f90 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/command_line_test.f90 b/test/command_line_test.f90 index b3604c90..9bb25f32 100644 --- a/test/command_line_test.f90 +++ b/test/command_line_test.f90 @@ -33,10 +33,14 @@ function check_flag_value() result(test_passes) integer exit_status, command_status character(len=132) command_message + !! Can't spawn an MPI process from an MPI process, this will fail if example is compiled with MPI and the test is too. + !! This triggers a full rebuild of the library and example if using caf. This can cause problems in some circumstances. + !! Try to sanitize the environment and unset FPM_FC if it is caf. call execute_command_line( & - command = "fpm run --example get-flag-value -- --input-file some_file_name", & + command = "if [[ ${FPM_FC:-x} == *'caf' ]] ; then unset FPM_FC ; fi ; & + &fpm run --example get-flag-value -- --input-file some_file_name", & wait = .true., exitstat = exit_status, cmdstat = command_status, cmdmsg = command_message & - ) + ) test_passes = exit_status == 0 end function From 806d3d8949269192f4c6a6cf082ca3a4f581b36d Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 20:56:58 -0500 Subject: [PATCH 06/18] CI: Build and run example without caf first This ensure that the example is built and ready to go before the tests are run. It is needed by the test and sometimes the build can throw errors if running fpm in parallel and you don't do this (because when running the tests in parallel, a serial library and version of the example code is built). --- .github/workflows/CI.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index edab46cb..c626a2b4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -36,22 +36,17 @@ jobs: --slave /usr/bin/g++ g++ /usr/bin/g++-${GCC_V} - name: Maybe install opencoarrays - if: steps.cache-opencoarrays.outputs.cache-hit != 'true' + # if: steps.cache-opencoarrays.outputs.cache-hit != 'true' run: | wget https://github.com/sourceryinstitute/OpenCoarrays/releases/download/${OC_V}/OpenCoarrays-${OC_V}.tar.gz tar xzvf OpenCoarrays-${OC_V}.tar.gz cd OpenCoarrays-${OC_V} mkdir -p "${HOME}/apps" cmake -S . -B build -DCMAKE_INSTALL_PREFIX="${HOME}/apps/OpenCoarrays" - cmake --build build -j cmake --build build -t install -j - cd .. echo "${HOME}/apps/OpenCoarrays/bin" >> $GITHUB_PATH - name: Build, run, and test run: | - caf --show - cafrun --show - export FPM_FC=caf - fpm build || fpm build --verbose - fpm test --runner "cafrun -n 2" || fpm test --runner "cafrun -n 2" --verbose + fpm run --example get-flag-value -- --input-file some_file_name + fpm test --compiler caf --runner "cafrun -n 2" From d781e8270e9b629a1358941f7829fe4cee2ac492 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 21:16:32 -0500 Subject: [PATCH 07/18] ci: fix bad cache path --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c626a2b4..af39e2ee 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -24,7 +24,7 @@ jobs: id: cache-opencoarrays uses: actions/cache@v4 with: - path: "${HOME}/app/OpenCoarrays/${OC_V}/" + path: "${HOME}/apps/OpenCoarrays/${OC_V}/" key: OC-${{ env.OC_V }} - name: Install GFortran @@ -36,7 +36,7 @@ jobs: --slave /usr/bin/g++ g++ /usr/bin/g++-${GCC_V} - name: Maybe install opencoarrays - # if: steps.cache-opencoarrays.outputs.cache-hit != 'true' + if: steps.cache-opencoarrays.outputs.cache-hit != 'true' run: | wget https://github.com/sourceryinstitute/OpenCoarrays/releases/download/${OC_V}/OpenCoarrays-${OC_V}.tar.gz tar xzvf OpenCoarrays-${OC_V}.tar.gz From dbe765a5ae8bb622f7162e940680f66fe0014efc Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 21:20:05 -0500 Subject: [PATCH 08/18] ci: install opencoarrays in the right place --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index af39e2ee..02838cc8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -24,7 +24,7 @@ jobs: id: cache-opencoarrays uses: actions/cache@v4 with: - path: "${HOME}/apps/OpenCoarrays/${OC_V}/" + path: "${HOME}/apps/OpenCoarrays/${OC_V}" key: OC-${{ env.OC_V }} - name: Install GFortran @@ -41,10 +41,10 @@ jobs: wget https://github.com/sourceryinstitute/OpenCoarrays/releases/download/${OC_V}/OpenCoarrays-${OC_V}.tar.gz tar xzvf OpenCoarrays-${OC_V}.tar.gz cd OpenCoarrays-${OC_V} - mkdir -p "${HOME}/apps" - cmake -S . -B build -DCMAKE_INSTALL_PREFIX="${HOME}/apps/OpenCoarrays" + mkdir -p "${HOME}/apps/OpenCoarrays/${OC_V}" + cmake -S . -B build -DCMAKE_INSTALL_PREFIX="${HOME}/apps/OpenCoarrays/${OC_V}" cmake --build build -t install -j - echo "${HOME}/apps/OpenCoarrays/bin" >> $GITHUB_PATH + echo "${HOME}/apps/OpenCoarrays/${OC_V}/bin" >> $GITHUB_PATH - name: Build, run, and test run: | From b86c24376ded576764e7f6d703313c22d5057b06 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 25 Jan 2024 21:27:24 -0500 Subject: [PATCH 09/18] ci: Fix caching --- .github/workflows/CI.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 02838cc8..576d239b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -24,7 +24,7 @@ jobs: id: cache-opencoarrays uses: actions/cache@v4 with: - path: "${HOME}/apps/OpenCoarrays/${OC_V}" + path: "~/apps/OpenCoarrays/" key: OC-${{ env.OC_V }} - name: Install GFortran @@ -41,8 +41,8 @@ jobs: wget https://github.com/sourceryinstitute/OpenCoarrays/releases/download/${OC_V}/OpenCoarrays-${OC_V}.tar.gz tar xzvf OpenCoarrays-${OC_V}.tar.gz cd OpenCoarrays-${OC_V} - mkdir -p "${HOME}/apps/OpenCoarrays/${OC_V}" - cmake -S . -B build -DCMAKE_INSTALL_PREFIX="${HOME}/apps/OpenCoarrays/${OC_V}" + mkdir -p "~/apps/OpenCoarrays/${OC_V}" + cmake -S . -B build -DCMAKE_INSTALL_PREFIX="~/apps/OpenCoarrays/${OC_V}" cmake --build build -t install -j echo "${HOME}/apps/OpenCoarrays/${OC_V}/bin" >> $GITHUB_PATH From 2facefded63a7da6578822befd9641075447c289 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 11:53:50 -0500 Subject: [PATCH 10/18] Tests: Test commandline on github actions I think this should work now, since I handled building the example file more carefully. --- test/main.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/main.f90 b/test/main.f90 index 533387f1..a59f2787 100644 --- a/test/main.f90 +++ b/test/main.f90 @@ -29,7 +29,7 @@ program main call test_result_test%report(passes, tests) call string_test%report(passes, tests) - if (.not. GitHub_CI()) call command_line_test%report(passes, tests) + call command_line_test%report(passes, tests) if (this_image()==1) print *, new_line('a'), "_________ In total, ",passes," of ",tests, " tests pass. _________" From e551cd8ddbc2a82726cf55f3002d615323f8341d Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 12:03:21 -0500 Subject: [PATCH 11/18] CI: Debug failed runs with verbose output --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 576d239b..3fd0f4c4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -48,5 +48,5 @@ jobs: - name: Build, run, and test run: | - fpm run --example get-flag-value -- --input-file some_file_name - fpm test --compiler caf --runner "cafrun -n 2" + fpm run --example get-flag-value -- --input-file some_file_name || fpm run --verbose --example get-flag-value -- --input-file some_file_name + fpm test --compiler caf --runner "cafrun -n 2" || !! --verbose From ba36b82b23f0ebfc335b4873e8fb93f4b25ed3e3 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 12:06:27 -0500 Subject: [PATCH 12/18] CI: Fix verbose debug output on GHA --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3fd0f4c4..3a71e679 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -49,4 +49,4 @@ jobs: - name: Build, run, and test run: | fpm run --example get-flag-value -- --input-file some_file_name || fpm run --verbose --example get-flag-value -- --input-file some_file_name - fpm test --compiler caf --runner "cafrun -n 2" || !! --verbose + fpm test --compiler caf --runner "cafrun -n 2" || fpm test --compiler caf --runner "cafrun -n 2" --verbose From 174a414d02988c336568c781e019db7dfac51269 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 12:17:17 -0500 Subject: [PATCH 13/18] CI: Add OC to path if restored from cache --- .github/workflows/CI.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3a71e679..6625b5ff 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -44,7 +44,11 @@ jobs: mkdir -p "~/apps/OpenCoarrays/${OC_V}" cmake -S . -B build -DCMAKE_INSTALL_PREFIX="~/apps/OpenCoarrays/${OC_V}" cmake --build build -t install -j - echo "${HOME}/apps/OpenCoarrays/${OC_V}/bin" >> $GITHUB_PATH + echo - name: Add to PATH if cache hit + + - name: Add to PATH if cache hit + if: steps.cache-opencoarrays.outputs.cache-hit == 'true' + run: echo "${HOME}/apps/OpenCoarrays/${{ env.OC_V }}/bin" >> $GITHUB_PATH"${HOME}/apps/OpenCoarrays/${OC_V}/bin" >> $GITHUB_PATH - name: Build, run, and test run: | From 67ae00bba3018e30af3c86e19ee497896147522c Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 12:19:33 -0500 Subject: [PATCH 14/18] CI: Fix copy pasta error --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6625b5ff..9381a1b8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -44,11 +44,11 @@ jobs: mkdir -p "~/apps/OpenCoarrays/${OC_V}" cmake -S . -B build -DCMAKE_INSTALL_PREFIX="~/apps/OpenCoarrays/${OC_V}" cmake --build build -t install -j - echo - name: Add to PATH if cache hit + echo echo "~/apps/OpenCoarrays/${{ env.OC_V }}/bin" >> $GITHUB_PATH - name: Add to PATH if cache hit if: steps.cache-opencoarrays.outputs.cache-hit == 'true' - run: echo "${HOME}/apps/OpenCoarrays/${{ env.OC_V }}/bin" >> $GITHUB_PATH"${HOME}/apps/OpenCoarrays/${OC_V}/bin" >> $GITHUB_PATH + run: echo "~/apps/OpenCoarrays/${{ env.OC_V }}/bin" >> $GITHUB_PATH - name: Build, run, and test run: | From d01a9574f28e3d7c80c739e30791166895fd8f60 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 12:26:06 -0500 Subject: [PATCH 15/18] CI: Debug path issues --- .github/workflows/CI.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9381a1b8..c2fc8576 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -44,13 +44,17 @@ jobs: mkdir -p "~/apps/OpenCoarrays/${OC_V}" cmake -S . -B build -DCMAKE_INSTALL_PREFIX="~/apps/OpenCoarrays/${OC_V}" cmake --build build -t install -j - echo echo "~/apps/OpenCoarrays/${{ env.OC_V }}/bin" >> $GITHUB_PATH + echo "${HOME}/apps/OpenCoarrays/${OC_V}/bin" >> $GITHUB_PATH - name: Add to PATH if cache hit if: steps.cache-opencoarrays.outputs.cache-hit == 'true' - run: echo "~/apps/OpenCoarrays/${{ env.OC_V }}/bin" >> $GITHUB_PATH + run: echo "${HOME}/apps/OpenCoarrays/${OC_V}/bin" >> $GITHUB_PATH - name: Build, run, and test run: | + ls ~/apps/OpenCoarrays/* + which caf + caf --version + caf --show fpm run --example get-flag-value -- --input-file some_file_name || fpm run --verbose --example get-flag-value -- --input-file some_file_name fpm test --compiler caf --runner "cafrun -n 2" || fpm test --compiler caf --runner "cafrun -n 2" --verbose From a565962ca987361e47a91321b5c624be77364fd5 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 12:53:28 -0500 Subject: [PATCH 16/18] add tests: are singleton bins OK? --- test/bin_test.f90 | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/test/bin_test.f90 b/test/bin_test.f90 index 2ae7f74d..d91f872d 100644 --- a/test/bin_test.f90 +++ b/test/bin_test.f90 @@ -29,11 +29,15 @@ function results() result(test_results) descriptions => & [ character(len=len(longest_description)) :: & "partitioning items nearly evenly across bins", & - "partitioning all item across all bins without item loss" & + "partitioning all item across all bins without item loss", & + "partitioning items such that each bin only has one works", & + "partitioning items such that some bins only have one works" & ], & outcomes => & [ verify_block_partitioning(), & - verify_all_items_partitioned() & + verify_all_items_partitioned(), & + verify_all_singleton_bins_are_ok(), & + verify_some_singleton_bins_are_ok() & ] & ) call assert(size(descriptions) == size(outcomes), "bin_test_m(results): size(descriptions) == size(outcomes)") @@ -73,4 +77,39 @@ function verify_all_items_partitioned() result(test_passes) end function + function verify_all_singleton_bins_are_ok() result(test_passes) + !! Verify that all singleton bins can be created and that the number of items equals the number of bins + type(bin_t) partition + logical test_passes + + type(bin_t), allocatable :: bins(:) + integer, parameter :: n_items=11, n_bins=11 + integer b + + bins = [( bin_t(num_items=n_items, num_bins=n_bins, bin_number=b), b = 1,n_bins )] + test_passes = sum([(bins(b)%last() - bins(b)%first() + 1, b = 1, n_bins)]) == n_items + + end function + + function verify_some_singleton_bins_are_ok() result(test_passes) + !! Verify that some singleton bins can be created and that the number of items equals the number of bins + type(bin_t) partition + logical test_passes + + type(bin_t), allocatable :: bins(:), more_bins(:) + integer, parameter :: n_bins=11, n_items=(n_bins + (n_bins/2)) + integer b + + bins = [( bin_t(num_items=n_items, num_bins=n_bins, bin_number=b), b = 1,n_bins )] + test_passes = sum([(bins(b)%last() - bins(b)%first() + 1, b = 1, n_bins)]) == n_items + + more_bins = [( bin_t(num_items=n_items, num_bins=n_bins, bin_number=b), b = 1,n_bins )] + associate(in_bin => [(more_bins(b)%last() - more_bins(b)%first() + 1, b = 1, n_bins)]) + associate(remainder => mod(n_items, n_bins), items_per_bin => n_items/n_bins) + test_passes = test_passes .and. & + all([(in_bin(1:remainder) == items_per_bin + 1)]) .and. all([(in_bin(remainder+1:) == items_per_bin)]) + end associate + end associate + + end function end module bin_test_m From 3f73b98ee876e9ee6e3244a7f7a0b7bc347cdfbd Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 12:55:09 -0500 Subject: [PATCH 17/18] CI: clean up build & test job --- .github/workflows/CI.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c2fc8576..5c408000 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -52,9 +52,8 @@ jobs: - name: Build, run, and test run: | - ls ~/apps/OpenCoarrays/* which caf - caf --version caf --show - fpm run --example get-flag-value -- --input-file some_file_name || fpm run --verbose --example get-flag-value -- --input-file some_file_name - fpm test --compiler caf --runner "cafrun -n 2" || fpm test --compiler caf --runner "cafrun -n 2" --verbose + # Build the example executable to test the commandline without caf first, since you cannot spawn new MPI jobs from within an MPI job + fpm run --example get-flag-value -- --input-file some_file_name + fpm test --compiler caf --runner "cafrun -n 2" From 65a30a6ddc9e601e15d625afbaacacd301cd1494 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Fri, 26 Jan 2024 16:21:58 -0500 Subject: [PATCH 18/18] Add tests for block partitioning with singletons Check that block partitioning works even in the presence of singletons. --- test/data_partition_test.f90 | 106 ++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 3 deletions(-) diff --git a/test/data_partition_test.f90 b/test/data_partition_test.f90 index c95b8356..340c4366 100644 --- a/test/data_partition_test.f90 +++ b/test/data_partition_test.f90 @@ -27,9 +27,19 @@ function results() result(test_results) type(test_result_t), allocatable :: test_results(:) test_results = [ & - test_result_t("partitioning data in nearly even blocks", verify_block_partitioning()), & + test_result_t("partitioning data in nearly even blocks", verify_block_partitioning(num_particles)), & + test_result_t("partitioning data in nearly even blocks when some blocks are singletons", & + verify_block_partitioning(num_images()+1)), & + test_result_t("bins of size 1 when set cardinality == num_images()", verify_block_partitioning_with_singletons()), & test_result_t("default image_number is this_image()", verify_default_image_number()), & + test_result_t("partitioning data into contiguous bins without overlap", & + verify_partitions_are_contiguous_without_overlap(num_particles)), & + test_result_t("contiguous non overlapping partitions with singletons", & + verify_partitions_are_contiguous_without_overlap(num_images())), & + test_result_t("contiguous non overlapping partitions with some singletons", & + verify_partitions_are_contiguous_without_overlap(num_images()+1)), & test_result_t("partitioning all data across all images without data loss", verify_all_particles_partitioned()), & + test_result_t("no data is lost when singleton bins are used", verify_all_particles_partitioned_on_singletons()), & test_result_t("gathering a 1D real array onto all images", verify_all_gather_1D_real_array()), & test_result_t("gathering dimension 1 of 2D real array onto all images witout dim argument", & verify_all_gather_2D_real_array()), & @@ -40,19 +50,54 @@ function results() result(test_results) ] end function - function verify_block_partitioning() result(test_passes) + function verify_testing_in_parallel() result(test_passes) + !! Verify that the test is being run in parallel + logical test_passes + test_passes = num_images() > 1 + end function + + function verify_block_partitioning(cardinality) result(test_passes) !! Verify that the data is partitioned across images evenly to !! within a difference of one datum between any two images. + integer, intent(in) :: cardinality type(data_partition_t) partition logical test_passes integer my_particles + associate( me=>this_image(), partition => data_partition_t(cardinality=cardinality)) + associate( my_first=>partition%first(me), my_last=>partition%last(me) ) + my_particles = my_last - my_first + 1 + associate( ni=>num_images() ) + associate( quotient=>cardinality/ni, remainder=>mod(cardinality,ni) ) + test_passes = quotient + merge(1, 0, me<=remainder) == my_particles + end associate + end associate + end associate + end associate + + end function + + function verify_block_partitioning_with_singletons() result(test_passes) + !! Verify that the data is partitioned so that each image has a bin of + !! size 1. + type(data_partition_t) partition, another_partition + logical test_passes + integer my_particles + integer num_particles + + num_particles = num_images() + another_partition = data_partition_t(cardinality=num_particles) + associate( me=>this_image(), partition => data_partition_t(cardinality=num_particles)) associate( my_first=>partition%first(me), my_last=>partition%last(me) ) my_particles = my_last - my_first + 1 associate( ni=>num_images() ) associate( quotient=>num_particles/ni, remainder=>mod(num_particles,ni) ) - test_passes = quotient + merge(1, 0, me<=remainder) == my_particles + test_passes = quotient == 1 & + .and. remainder == 0 & + .and. my_particles == 1 & + .and. my_last == my_first & + .and. my_first == me end associate end associate end associate @@ -60,6 +105,41 @@ function verify_block_partitioning() result(test_passes) end function + function verify_partitions_are_contiguous_without_overlap(cardinality) result(test_passes) + !! Verify that the data is partitioned across images into contiguous bins without overlap + integer, intent(in) :: cardinality + logical test_passes + type(data_partition_t) partition + + associate( me=>this_image(), partition => data_partition_t(cardinality=cardinality)) + associate( my_first=>partition%first(me), my_last=>partition%last(me) ) + associate(ni => num_images()) + if (me > 1) then + associate( your_first=>partition%first(me-1), your_last=>partition%last(me-1) ) + test_passes = my_first <= my_last & + .and. your_first <= your_last & + .and. my_first >= 1 & + .and. my_last <= cardinality & + .and. my_first == your_last + 1 + end associate + else if (me == 1 .and. ni > 1) then + associate( your_first=>partition%first(me+1), your_last=>partition%last(me+1) ) + test_passes = my_first <= my_last & + .and. your_first <= your_last & + .and. my_first >= 1 & + .and. my_last <= cardinality & + .and. my_last == your_first - 1 + end associate + else if (ni == 1) then + test_passes = my_first <= my_last & + .and. my_first >= 1 & + .and. my_last <= cardinality + end if + end associate + end associate + end associate + end function + function verify_default_image_number() result(test_passes) !! Verify that the first and last functions assume image_number == this_image() if image_number is not present type(data_partition_t) partition @@ -86,6 +166,26 @@ function verify_all_particles_partitioned() result(test_passes) end associate end function + function verify_all_particles_partitioned_on_singletons() result(test_passes) + !! Verify that the number of particles on each image sums to the + !! total number of particles distributed when the cardinality of the + !! partitioned set is equal to num_images() + type(data_partition_t) partition + logical test_passes + integer particles + integer num_particles + num_particles = num_images() + + associate( me=>this_image(), partition => data_partition_t(cardinality=num_particles)) + associate( my_first=>partition%first(me), my_last=>partition%last(me) ) + particles = my_last - my_first + 1 + test_passes = particles == 1 + call co_sum(particles) + test_passes = test_passes .and. num_particles == particles + end associate + end associate + end function + function verify_all_gather_1D_real_array() result(test_passes) type(data_partition_t) partition logical test_passes