From e1af9312a49a9960975242dc903c72197e18dcb6 Mon Sep 17 00:00:00 2001 From: Max Williams Date: Sat, 13 Feb 2021 09:57:22 +0000 Subject: [PATCH 1/6] update gitignore - build/ directory - any compiled objects --- .gitignore | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4c63ad4..bfeb24f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,13 @@ # IntelliJ .idea/ -cmake-build-*/ \ No newline at end of file +cmake-build-*/ + +# Build Dirs +build/ + +# Build Artifact +*.dylib +*.a +*.mod +*.o \ No newline at end of file From 542a80d5b0efdb16d00d636c9c1185d038348bba Mon Sep 17 00:00:00 2001 From: Max Williams Date: Sun, 14 Feb 2021 13:07:52 +0000 Subject: [PATCH 2/6] Initial attempt at wrapping MPI_REDUCE using mpilib20_reduce_m module Current TODOs (in-file) * Unravel how MPI_Datatype operates * Overload for MPI_IN_PLACE? * Testing --- src/CMakeLists.txt | 1 + src/bindings/mpi_bindings.F90 | 12 ++++-- src/routines/generic_templates.md | 23 +++++++++++ src/routines/mpilib20_reduce.F90 | 64 +++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/routines/generic_templates.md create mode 100644 src/routines/mpilib20_reduce.F90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa6774b..6c1c43d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories("${CMAKE_SOURCE_DIR}/src") set(SOURCE_CODE src/mpilib20.F90 src/routines/mpilib20_init_finalise.F90 + src/routines/mpilib20_reduce.F90 src/bindings/mpi_bindings.F90 src/errors_warnings/asserts.F90 PARENT_SCOPE diff --git a/src/bindings/mpi_bindings.F90 b/src/bindings/mpi_bindings.F90 index c636cf5..7b4886d 100644 --- a/src/bindings/mpi_bindings.F90 +++ b/src/bindings/mpi_bindings.F90 @@ -19,6 +19,7 @@ module mpi_bindings MPI_FINALIZE, & MPI_COMM_SIZE, & MPI_GROUP_SIZE, & + MPI_REDUCE, & ! Data types MPI_COMM_WORLD, & @@ -26,6 +27,7 @@ module mpi_bindings MPI_THREAD_FUNNELED, & MPI_THREAD_SERIALIZED, & MPI_THREAD_MULTIPLE, & + MPI_INTEGER, & ! Derived types MPI_Comm, & @@ -57,13 +59,15 @@ module mpi_bindings MPI_FINALIZE, & MPI_COMM_SIZE, & MPI_GROUP_SIZE, & + MPI_REDUCE, & ! Data types - MPI_COMM_WORLD, & - MPI_THREAD_SINGLE, & - MPI_THREAD_FUNNELED, & + MPI_COMM_WORLD, & + MPI_THREAD_SINGLE, & + MPI_THREAD_FUNNELED, & MPI_THREAD_SERIALIZED, & - MPI_THREAD_MULTIPLE + MPI_THREAD_MULTIPLE, & + MPI_INTEGER implicit none public diff --git a/src/routines/generic_templates.md b/src/routines/generic_templates.md new file mode 100644 index 0000000..867face --- /dev/null +++ b/src/routines/generic_templates.md @@ -0,0 +1,23 @@ +# Generic Subroutine Templates +Store templates for the most generic form of a subroutine to be overloaded. Allowing rapid replication. + +## MPI_REDUCE +```fortran +!> MPI_REDUCE WRAPPER: INTEGER + subroutine mpilib20_reduce_type(sendbuf, recvbuf, op, root, mpi_env) + use mpi_bindings, only : MPI_REDUCE, MPI_Op, & + MPI_TYPE + !> Variable containing set to be sent + type(MPI_TYPE), intent(in) :: sendbuf + !> Variable to receive reduced set + type(MPI_TYPE), intent(inout) :: recvbuf + !> MPI Operation + type(MPI_Op), intent(in) :: op + !> Rank of the process to receive the reduced set + integer, intent(in) :: root + !> Instance of the MPI environment + type(mpi_env_type), intent(inout) :: mpi_env + + call MPI_REDUCE(sendbuf, recvbuf, 1, MPI_TYPE, op, root, mpi_env%comm, mpi_env%ierror) + end subroutine mpilib20_reduce_type +```` \ No newline at end of file diff --git a/src/routines/mpilib20_reduce.F90 b/src/routines/mpilib20_reduce.F90 new file mode 100644 index 0000000..a344b4b --- /dev/null +++ b/src/routines/mpilib20_reduce.F90 @@ -0,0 +1,64 @@ +!> Wrapping of the MPI_REDUCE methods +!> TODOs +!> Unravel how MPI_Datatype operates +!> Overload for MPI_IN_PLACE? +!> Testing +module mpilib20_reduce_m + + use mpilib20_init_finalise, only : mpi_env_type + + implicit none + + private + + interface mpilib20_reduce + end interface + + public :: mpilib20_REDUCE + +contains + + !> MPI_REDUCE WRAPPER: INTEGER + subroutine mpilib20_reduce_int_scalar(sendbuf, recvbuf, operation, root, mpi_env) + use mpi_bindings, only : MPI_REDUCE, MPI_Op, & + MPI_Datatype, MPI_INTEGER + !> Variable containing set to be sent + type(MPI_Datatype), intent(in) :: sendbuf + !> Variable to receive reduced set + type(MPI_Datatype), intent(inout) :: recvbuf + !> MPI Operation + type(MPI_Op), intent(in) :: operation + !> Rank of the process to receive the reduced set + integer, intent(in) :: root + !> Instance of the MPI environment + type(mpi_env_type), intent(inout) :: mpi_env + + call MPI_REDUCE(sendbuf, recvbuf, 1, MPI_INTEGER, operation, root, mpi_env%comm, mpi_env%ierror) + + end subroutine mpilib20_reduce_int_scalar + + !> MPI_REDUCE WRAPPER: INTEGER(:) + !> Rank 1 arrays don't require flattening + subroutine mpilib20_reduce_int_vec(sendbuf, recvbuf, operation, root, mpi_env) + use mpi_bindings, only : MPI_REDUCE, MPI_Op, & + MPI_Datatype, MPI_INTEGER + !> Variable containing set to be sent + type(MPI_Datatype), intent(in) :: sendbuf(:) + !> Variable to receive reduced set + type(MPI_Datatype), intent(inout) :: recvbuf(:) + !> MPI Operation + type(MPI_Op), intent(in) :: operation + !> Rank of the process to receive the reduced set + integer, intent(in) :: root + !> Instance of the MPI environment + type(mpi_env_type), intent(inout) :: mpi_env + !> elements in each buffer + integer :: count + !> Element count based-on receiving buffer size + count = size(recvbuf) + + call MPI_REDUCE(sendbuf, recvbuf, count, MPI_INTEGER, operation, root, mpi_env%comm, mpi_env%ierror) + + end subroutine mpilib20_reduce_int_vec + +end module mpilib20_reduce_m From d62b742920663d37de57822f3936b0a8fea56ae9 Mon Sep 17 00:00:00 2001 From: Max Williams Date: Sun, 14 Feb 2021 13:17:52 +0000 Subject: [PATCH 3/6] add module procedures to interface mpilib20_reduce --- src/routines/mpilib20_reduce.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/routines/mpilib20_reduce.F90 b/src/routines/mpilib20_reduce.F90 index a344b4b..2161c19 100644 --- a/src/routines/mpilib20_reduce.F90 +++ b/src/routines/mpilib20_reduce.F90 @@ -12,6 +12,8 @@ module mpilib20_reduce_m private interface mpilib20_reduce + module procedure mpilib20_reduce_int_scalar + module procedure mpilib20_reduce_int_vec end interface public :: mpilib20_REDUCE From e219006784ee543528d6c555ae06bc190c2fb8cc Mon Sep 17 00:00:00 2001 From: Max Williams Date: Mon, 15 Feb 2021 08:57:19 +0000 Subject: [PATCH 4/6] The root argument of mpilib20_reduce_() generics is optional, allowing overiding of the default master rank within mpilib20_init_finalise. --- src/routines/mpilib20_reduce.F90 | 41 ++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/routines/mpilib20_reduce.F90 b/src/routines/mpilib20_reduce.F90 index 2161c19..014ac97 100644 --- a/src/routines/mpilib20_reduce.F90 +++ b/src/routines/mpilib20_reduce.F90 @@ -21,41 +21,58 @@ module mpilib20_reduce_m contains !> MPI_REDUCE WRAPPER: INTEGER - subroutine mpilib20_reduce_int_scalar(sendbuf, recvbuf, operation, root, mpi_env) + subroutine mpilib20_reduce_int_scalar(sendbuf, recvbuf, operation, mpi_env, root) use mpi_bindings, only : MPI_REDUCE, MPI_Op, & MPI_Datatype, MPI_INTEGER + use mpilib20_init_finalise, only : root_id !> Variable containing set to be sent type(MPI_Datatype), intent(in) :: sendbuf !> Variable to receive reduced set type(MPI_Datatype), intent(inout) :: recvbuf !> MPI Operation - type(MPI_Op), intent(in) :: operation - !> Rank of the process to receive the reduced set - integer, intent(in) :: root + type(MPI_Op), intent(in) :: operation !> Instance of the MPI environment - type(mpi_env_type), intent(inout) :: mpi_env + type(mpi_env_type), intent(inout) :: mpi_env + !> Rank of the process to receive the reduced set (override default) + integer, optional, intent(in) :: root + integer :: use_root - call MPI_REDUCE(sendbuf, recvbuf, 1, MPI_INTEGER, operation, root, mpi_env%comm, mpi_env%ierror) + !> Overide root process if passed + if (present(root)) then + use_root = root + else + use_root = root_id + end if + + call MPI_REDUCE(sendbuf, recvbuf, 1, MPI_INTEGER, operation, use_root, mpi_env%comm, mpi_env%ierror) end subroutine mpilib20_reduce_int_scalar !> MPI_REDUCE WRAPPER: INTEGER(:) !> Rank 1 arrays don't require flattening - subroutine mpilib20_reduce_int_vec(sendbuf, recvbuf, operation, root, mpi_env) + subroutine mpilib20_reduce_int_vec(sendbuf, recvbuf, operation, mpi_env, root) use mpi_bindings, only : MPI_REDUCE, MPI_Op, & MPI_Datatype, MPI_INTEGER + use mpilib20_init_finalise, only : root_id !> Variable containing set to be sent - type(MPI_Datatype), intent(in) :: sendbuf(:) + type(MPI_Datatype), intent(in) :: sendbuf(:) !> Variable to receive reduced set - type(MPI_Datatype), intent(inout) :: recvbuf(:) + type(MPI_Datatype), intent(inout) :: recvbuf(:) !> MPI Operation type(MPI_Op), intent(in) :: operation - !> Rank of the process to receive the reduced set - integer, intent(in) :: root !> Instance of the MPI environment type(mpi_env_type), intent(inout) :: mpi_env - !> elements in each buffer + !> Rank of the process to receive the reduced set (override default) + integer, optional, intent(in) :: root integer :: count + integer :: use_root + + !> Overide root process if passed + if (present(root)) then + use_root = root + else + use_root = root_id + end if !> Element count based-on receiving buffer size count = size(recvbuf) From ecd0bf742eb7643c1ff6db1c5264d71867d56ab3 Mon Sep 17 00:00:00 2001 From: Max Williams Date: Sat, 20 Feb 2021 17:48:21 +0000 Subject: [PATCH 5/6] PR changes - remove generic_template file - useful locally if useful during development - mpilib20_REDUCE interface -> mpilib20_reduce - global imports moved to module scope - recvbuf (receiving buffer) for integer case -> intent(out) - use_rank (integer) renamed to process_id. Persistent rank is then renamed to process in calls. - reduce verbosity when inferring dimension of buffers. Use size(recvbuf) rather than storing in `count` variable. - add assert to check that sendbuf and recvbuf are equal dimension - update todos at module docs (remaining types etc) - update todos at subroutine level: usage examples --- src/routines/generic_templates.md | 23 --------- src/routines/mpilib20_reduce.F90 | 83 +++++++++++++++++-------------- 2 files changed, 47 insertions(+), 59 deletions(-) delete mode 100644 src/routines/generic_templates.md diff --git a/src/routines/generic_templates.md b/src/routines/generic_templates.md deleted file mode 100644 index 867face..0000000 --- a/src/routines/generic_templates.md +++ /dev/null @@ -1,23 +0,0 @@ -# Generic Subroutine Templates -Store templates for the most generic form of a subroutine to be overloaded. Allowing rapid replication. - -## MPI_REDUCE -```fortran -!> MPI_REDUCE WRAPPER: INTEGER - subroutine mpilib20_reduce_type(sendbuf, recvbuf, op, root, mpi_env) - use mpi_bindings, only : MPI_REDUCE, MPI_Op, & - MPI_TYPE - !> Variable containing set to be sent - type(MPI_TYPE), intent(in) :: sendbuf - !> Variable to receive reduced set - type(MPI_TYPE), intent(inout) :: recvbuf - !> MPI Operation - type(MPI_Op), intent(in) :: op - !> Rank of the process to receive the reduced set - integer, intent(in) :: root - !> Instance of the MPI environment - type(mpi_env_type), intent(inout) :: mpi_env - - call MPI_REDUCE(sendbuf, recvbuf, 1, MPI_TYPE, op, root, mpi_env%comm, mpi_env%ierror) - end subroutine mpilib20_reduce_type -```` \ No newline at end of file diff --git a/src/routines/mpilib20_reduce.F90 b/src/routines/mpilib20_reduce.F90 index 014ac97..8779e76 100644 --- a/src/routines/mpilib20_reduce.F90 +++ b/src/routines/mpilib20_reduce.F90 @@ -1,11 +1,17 @@ !> Wrapping of the MPI_REDUCE methods !> TODOs -!> Unravel how MPI_Datatype operates -!> Overload for MPI_IN_PLACE? +!> Up to rank 3 arrays +!> Remaining types (parametized derived types for precisions?) +!> real(sp), real(dp), real(qp) +!> complex +!> Overload for MPI_IN_PLACE - optional logical could work !> Testing +!> Refactor when root_id moved to mpi_env_type module mpilib20_reduce_m - use mpilib20_init_finalise, only : mpi_env_type + use mpilib20_init_finalise, only : mpi_env_type, root_id + use mpi_bindings, only : MPI_REDUCE, MPI_Op, & + MPI_INTEGER implicit none @@ -16,68 +22,73 @@ module mpilib20_reduce_m module procedure mpilib20_reduce_int_vec end interface - public :: mpilib20_REDUCE + public :: mpilib20_reduce contains - !> MPI_REDUCE WRAPPER: INTEGER - subroutine mpilib20_reduce_int_scalar(sendbuf, recvbuf, operation, mpi_env, root) - use mpi_bindings, only : MPI_REDUCE, MPI_Op, & - MPI_Datatype, MPI_INTEGER - use mpilib20_init_finalise, only : root_id + + !> Reduces values on all processes to a single value + !> on process defined by process_id + !> TODO usage examples + subroutine mpilib20_reduce_int_scalar(sendbuf, recvbuf, & + operation, mpi_env, & + process_id) !> Variable containing set to be sent - type(MPI_Datatype), intent(in) :: sendbuf + type(MPI_INTEGER), intent(in) :: sendbuf !> Variable to receive reduced set - type(MPI_Datatype), intent(inout) :: recvbuf + type(MPI_INTEGER), intent(out) :: recvbuf !> MPI Operation - type(MPI_Op), intent(in) :: operation + type(MPI_Op), intent(in) :: operation !> Instance of the MPI environment - type(mpi_env_type), intent(inout) :: mpi_env + type(mpi_env_type), intent(out) :: mpi_env !> Rank of the process to receive the reduced set (override default) - integer, optional, intent(in) :: root - integer :: use_root + integer, optional, intent(in) :: process_id + integer :: process !> Overide root process if passed - if (present(root)) then - use_root = root + if (present(process_id)) then + process = process_id else - use_root = root_id + process = root_id end if - call MPI_REDUCE(sendbuf, recvbuf, 1, MPI_INTEGER, operation, use_root, mpi_env%comm, mpi_env%ierror) + call MPI_REDUCE(sendbuf, recvbuf, 1, MPI_INTEGER, operation, process, & + mpi_env%comm, mpi_env%ierror) end subroutine mpilib20_reduce_int_scalar - !> MPI_REDUCE WRAPPER: INTEGER(:) - !> Rank 1 arrays don't require flattening - subroutine mpilib20_reduce_int_vec(sendbuf, recvbuf, operation, mpi_env, root) - use mpi_bindings, only : MPI_REDUCE, MPI_Op, & - MPI_Datatype, MPI_INTEGER - use mpilib20_init_finalise, only : root_id + + !> Reduces values on all processes to a single value + !> on process defined by process_id + !> TODO usage examples + subroutine mpilib20_reduce_int_vec(sendbuf, recvbuf, & + operation, mpi_env, & + process_id) !> Variable containing set to be sent - type(MPI_Datatype), intent(in) :: sendbuf(:) + type(MPI_INTEGER), intent(in) :: sendbuf(:) !> Variable to receive reduced set - type(MPI_Datatype), intent(inout) :: recvbuf(:) + type(MPI_INTEGER), intent(inout) :: recvbuf(:) !> MPI Operation type(MPI_Op), intent(in) :: operation !> Instance of the MPI environment type(mpi_env_type), intent(inout) :: mpi_env !> Rank of the process to receive the reduced set (override default) - integer, optional, intent(in) :: root - integer :: count - integer :: use_root + integer, optional, intent(in) :: process_id + integer :: process !> Overide root process if passed - if (present(root)) then - use_root = root + if (present(process_id)) then + process = process_id else - use_root = root_id + process = root_id end if - !> Element count based-on receiving buffer size - count = size(recvbuf) - call MPI_REDUCE(sendbuf, recvbuf, count, MPI_INTEGER, operation, root, mpi_env%comm, mpi_env%ierror) + call assert(size(sendbuf) == size(recvbuf), "size(sendbuf) /= size(recvbuf)") + + call MPI_REDUCE(sendbuf, recvbuf, size(recvbuf), MPI_INTEGER, operation, process, & + mpi_env%comm, mpi_env%ierror) end subroutine mpilib20_reduce_int_vec + end module mpilib20_reduce_m From ebf7145be11d367f00a66d5f609ae1a012ca666d Mon Sep 17 00:00:00 2001 From: Max Williams Date: Wed, 10 Mar 2021 20:39:51 +0000 Subject: [PATCH 6/6] Remove non-existent file from src/CMakeLists.txt --- src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a9fd598..ea958bc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,5 @@ set(SOURCE_CODE src/routines/mpilib20_reduce.F90 src/bindings/mpi_bindings.F90 src/errors_warnings/asserts.F90 - src/utilities/internal_utils.F90 PARENT_SCOPE )