From ab8533fa97d223331e82a9d9cb73b9c8cd1431d7 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Tue, 31 Oct 2023 11:45:07 +0100 Subject: [PATCH 01/16] add Fortran API for redistribution --- src/atlas/CMakeLists.txt | 2 + .../detail/RedistributionInterface.cc | 35 +++++++ .../detail/RedistributionInterface.h | 61 ++++++++++++ src/atlas_f/CMakeLists.txt | 4 + .../atlas_Redistribution_module.F90 | 98 +++++++++++++++++++ 5 files changed, 200 insertions(+) create mode 100644 src/atlas/redistribution/detail/RedistributionInterface.cc create mode 100644 src/atlas/redistribution/detail/RedistributionInterface.h create mode 100644 src/atlas_f/redistribution/atlas_Redistribution_module.F90 diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 3655519be..6e0d3d01b 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -693,6 +693,8 @@ linalg/dense/MatrixMultiply_EckitLinalg.cc list (APPEND atlas_redistribution_srcs redistribution/Redistribution.h redistribution/Redistribution.cc +redistribution/detail/RedistributionInterface.h +redistribution/detail/RedistributionInterface.cc redistribution/detail/RedistributionImpl.h redistribution/detail/RedistributionImpl.cc redistribution/detail/RedistributionImplFactory.h diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc new file mode 100644 index 000000000..cc0e0d2c4 --- /dev/null +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2013 ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ + +#include + +#include "RedistributionInterface.h" + +//#include "atlas/functionspace/FunctionSpace.h" +#include "atlas/functionspace/detail/FunctionSpaceImpl.h" + +namespace atlas { + +// ---------------------------------------------------------------------------- +// Fortran interfaces +// ---------------------------------------------------------------------------- + +extern "C" { + +const Redistribution* atlas__Redistribution__new( + const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2) { + return new Redistribution(fspace1, fspace2); +} +} + + +// ---------------------------------------------------------------------------- + +} // namespace atlas diff --git a/src/atlas/redistribution/detail/RedistributionInterface.h b/src/atlas/redistribution/detail/RedistributionInterface.h new file mode 100644 index 000000000..0518d4273 --- /dev/null +++ b/src/atlas/redistribution/detail/RedistributionInterface.h @@ -0,0 +1,61 @@ +/* + * (C) Copyright 2013 ECMWF. + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + * In applying this licence, ECMWF does not waive the privileges and immunities + * granted to it by virtue of its status as an intergovernmental organisation + * nor does it submit to any jurisdiction. + */ +#pragma once + +//#include "atlas/functionspace/detail/FunctionSpaceImpl.h" +#include "atlas/redistribution/Redistribution.h" + +namespace atlas { +namespace functionspace{ +class FunctionSpaceImpl; +} +namespace field { +class FieldSetImpl; +} +namespace grid { +class DistributionImpl; +} +} // namespace atlas + +namespace atlas { +namespace grid { +namespace detail { +namespace grid { +class Grid; +} // namespace grid +} // namespace detail +} // namespace grid +using GridImpl = grid::detail::grid::Grid; +} // namespace atlas + +namespace atlas { +namespace grid { +namespace detail { +namespace partitioner { +class Partitioner; +} // namespace partitioner +} // namespace detail +} // namespace grid +using PartitionerImpl = grid::detail::partitioner::Partitioner; +} // namespace atlas + + +namespace atlas { + +// ------------------------------------------------------------------- +// C wrapper interfaces to C++ routines +extern "C" { + +const Redistribution* atlas__Redistribution__new( + const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2); + +} + +} // namespace atlas diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 7075be1bb..a59e7f9c2 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -130,6 +130,9 @@ generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/functionspace/EdgeColumns.h generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/functionspace/detail/PointCloudInterface.h MODULE atlas_functionspace_PointCloud_c_binding OUTPUT functionspace_PointCloud_c_binding.f90) +generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/redistribution/detail/RedistributionInterface.h + MODULE atlas_redistribution_c_binding + OUTPUT redistribution_c_binding.f90) if( atlas_HAVE_ATLAS_NUMERICS ) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/numerics/Nabla.h) @@ -237,6 +240,7 @@ ecbuild_add_library( TARGET atlas_f parallel/atlas_Checksum_module.fypp parallel/atlas_HaloExchange_module.fypp projection/atlas_Projection_module.F90 + redistribution/atlas_Redistribution_module.F90 internals/atlas_read_file.h internals/atlas_read_file.cc internals/Library.h diff --git a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 new file mode 100644 index 000000000..08005e659 --- /dev/null +++ b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 @@ -0,0 +1,98 @@ +! (C) Copyright 2013 ECMWF. +! +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +! In applying this licence, ECMWF does not waive the privileges and immunities +! granted to it by virtue of its status as an intergovernmental organisation nor +! does it submit to any jurisdiction. + +#include "atlas/atlas_f.h" + +module atlas_Redistribution_module + +use, intrinsic :: iso_c_binding, only : c_ptr +use atlas_functionspace_module, only : atlas_FunctionSpace +use fckit_owned_object_module, only: fckit_owned_object + +implicit none + +public :: atlas_Redistribution + +private + +!----------------------------- +! atlas_Redistribution ! +!----------------------------- + + +!------------------------------------------------------------------------------ +TYPE, extends(fckit_owned_object) :: atlas_Redistribution + +! Purpose : +! ------- +! *Redistribution* : Object passed from atlas to inspect redistribution + +! Methods : +! ------- + +! Author : +! ------ + +!------------------------------------------------------------------------------ +contains + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Redistribution__final_auto +#endif +END TYPE atlas_Redistribution + +!------------------------------------------------------------------------------ + +interface atlas_Redistribution + module procedure atlas_Redistribution__cptr + module procedure atlas_Redistribution__ctor +end interface + +private :: c_ptr +private :: fckit_owned_object + +!======================================================== +contains +!======================================================== +! ----------------------------------------------------------------------------- +! Redistribution routines + +function atlas_Redistribution__cptr( cptr ) result(this) + use atlas_redistribution_c_binding + type(atlas_Redistribution) :: this + type(c_ptr), intent(in) :: cptr + call this%reset_c_ptr( cptr ) + call this%return() +end function + +function atlas_Redistribution__ctor( fspace1, fspace2 ) result(this) + use atlas_redistribution_c_binding + type(atlas_FunctionSpace), intent(in) :: fspace1, fspace2 + type(atlas_Redistribution) :: this + call this%reset_c_ptr( atlas__Redistribution__new(fspace1%CPTR_PGIBUG_A, fspace2%CPTR_PGIBUG_A) ) + call this%return() +end function + +! ---------------------------------------------------------------------------------------- + +#if FCKIT_FINAL_NOT_INHERITING +ATLAS_FINAL subroutine atlas_Redistribution__final_auto(this) + type(atlas_Redistribution), intent(inout) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Redistribution__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine +#endif + +! ---------------------------------------------------------------------------------------- + +end module atlas_Redistribution_module From a6a501c9a196a02838ff9b464b24a3ff21e6b40b Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Tue, 31 Oct 2023 16:31:51 +0100 Subject: [PATCH 02/16] 1) add a unit test for Fortran API redistribution; 2) fix compile bugs (tnx Willem) --- .../detail/RedistributionInterface.cc | 19 ++++-- .../detail/RedistributionInterface.h | 42 +++--------- .../atlas_Redistribution_module.F90 | 25 +++++-- src/tests/redistribution/CMakeLists.txt | 9 +++ .../redistribution/fctest_redistribution.F90 | 67 +++++++++++++++++++ 5 files changed, 119 insertions(+), 43 deletions(-) create mode 100644 src/tests/redistribution/fctest_redistribution.F90 diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc index cc0e0d2c4..ac010842c 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.cc +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -10,12 +10,13 @@ #include +#include "RedistributionImpl.h" #include "RedistributionInterface.h" -//#include "atlas/functionspace/FunctionSpace.h" -#include "atlas/functionspace/detail/FunctionSpaceImpl.h" +#include "atlas/redistribution/detail/RedistributionImplFactory.h" namespace atlas { +namespace redistribution { // ---------------------------------------------------------------------------- // Fortran interfaces @@ -23,13 +24,21 @@ namespace atlas { extern "C" { -const Redistribution* atlas__Redistribution__new( - const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2) { - return new Redistribution(fspace1, fspace2); +detail::RedistributionImpl* atlas__Redistribution__new__config( + const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2, + const eckit::Configuration* config) { + ATLAS_ASSERT(config != nullptr); + std::string type; + config->get("type", type); + auto redist = redistribution::detail::RedistributionImplFactory::build(type); + redist->setup(fspace1, fspace2); + return redist; } + } // ---------------------------------------------------------------------------- +} // namespace redistribution } // namespace atlas diff --git a/src/atlas/redistribution/detail/RedistributionInterface.h b/src/atlas/redistribution/detail/RedistributionInterface.h index 0518d4273..e1fe3504c 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.h +++ b/src/atlas/redistribution/detail/RedistributionInterface.h @@ -9,53 +9,31 @@ */ #pragma once -//#include "atlas/functionspace/detail/FunctionSpaceImpl.h" -#include "atlas/redistribution/Redistribution.h" +namespace eckit { +class Configuration; +} namespace atlas { namespace functionspace{ class FunctionSpaceImpl; } -namespace field { -class FieldSetImpl; -} -namespace grid { -class DistributionImpl; -} -} // namespace atlas - -namespace atlas { -namespace grid { -namespace detail { -namespace grid { -class Grid; -} // namespace grid -} // namespace detail -} // namespace grid -using GridImpl = grid::detail::grid::Grid; } // namespace atlas namespace atlas { -namespace grid { +namespace redistribution { namespace detail { -namespace partitioner { -class Partitioner; -} // namespace partitioner -} // namespace detail -} // namespace grid -using PartitionerImpl = grid::detail::partitioner::Partitioner; -} // namespace atlas - - -namespace atlas { +class RedistributionImpl; +} // ------------------------------------------------------------------- // C wrapper interfaces to C++ routines extern "C" { -const Redistribution* atlas__Redistribution__new( - const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2); +detail::RedistributionImpl* atlas__Redistribution__new__config( + const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2, + const eckit::Configuration* config); } +} // namespace redistribution } // namespace atlas diff --git a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 index 08005e659..c67d1a3d4 100644 --- a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 +++ b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 @@ -11,6 +11,7 @@ module atlas_Redistribution_module use, intrinsic :: iso_c_binding, only : c_ptr +use atlas_config_module, only : atlas_Config use atlas_functionspace_module, only : atlas_FunctionSpace use fckit_owned_object_module, only: fckit_owned_object @@ -49,8 +50,8 @@ module atlas_Redistribution_module !------------------------------------------------------------------------------ interface atlas_Redistribution - module procedure atlas_Redistribution__cptr - module procedure atlas_Redistribution__ctor + module procedure ctor_cptr + module procedure ctor_create end interface private :: c_ptr @@ -62,7 +63,13 @@ module atlas_Redistribution_module ! ----------------------------------------------------------------------------- ! Redistribution routines -function atlas_Redistribution__cptr( cptr ) result(this) +function empty_config() result(config) + type(atlas_Config) :: config + config = atlas_Config() + call config%return() +end function + +function ctor_cptr( cptr ) result(this) use atlas_redistribution_c_binding type(atlas_Redistribution) :: this type(c_ptr), intent(in) :: cptr @@ -70,11 +77,17 @@ function atlas_Redistribution__cptr( cptr ) result(this) call this%return() end function -function atlas_Redistribution__ctor( fspace1, fspace2 ) result(this) +function ctor_create( fspace1, fspace2, redist_name ) result(this) use atlas_redistribution_c_binding - type(atlas_FunctionSpace), intent(in) :: fspace1, fspace2 + class(atlas_FunctionSpace), intent(in) :: fspace1, fspace2 + character(len=*), intent(in), optional :: redist_name type(atlas_Redistribution) :: this - call this%reset_c_ptr( atlas__Redistribution__new(fspace1%CPTR_PGIBUG_A, fspace2%CPTR_PGIBUG_A) ) + type(atlas_Config) :: config + config = empty_config() + call config%set("type", "RedistributeGeneric") + if (present(redist_name)) call config%set("type", redist_name) + call this%reset_c_ptr( atlas__Redistribution__new__config(fspace1%CPTR_PGIBUG_A, fspace2%CPTR_PGIBUG_A, config%CPTR_PGIBUG_B) ) + call config%final() call this%return() end function diff --git a/src/tests/redistribution/CMakeLists.txt b/src/tests/redistribution/CMakeLists.txt index 0a3a5a836..e188b2d8b 100644 --- a/src/tests/redistribution/CMakeLists.txt +++ b/src/tests/redistribution/CMakeLists.txt @@ -7,6 +7,15 @@ if( atlas_HAVE_ATLAS_FUNCTIONSPACE ) +add_fctest( TARGET atlas_fctest_redistribution + MPI 4 + CONDITION eckit_HAVE_MPI + LINKER_LANGUAGE Fortran + SOURCES fctest_redistribution.F90 + LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} +) + ecbuild_add_test( TARGET atlas_test_redistribution_structured SOURCES test_redistribution_structured.cc MPI 8 diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 new file mode 100644 index 000000000..dfa02a29e --- /dev/null +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -0,0 +1,67 @@ +! (C) Copyright 2013 ECMWF. +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +! In applying this licence, ECMWF does not waive the privileges and immunities +! granted to it by virtue of its status as an intergovernmental organisation nor +! does it submit to any jurisdiction. + +! This File contains Unit Tests for testing the +! C++ / Fortran Interfaces to the State Datastructure +! +! @author Willem Deconinck +! @author Slavko Brdar + +#include "fckit/fctest.h" + +! ----------------------------------------------------------------------------- + +module fcta_Redistribution_fxt +use atlas_module +use, intrinsic :: iso_c_binding +implicit none +character(len=1024) :: msg +contains + +end module + +! ----------------------------------------------------------------------------- + +TESTSUITE_WITH_FIXTURE(fcta_Redistribution,fcta_Redistribution_fxt) + +! ----------------------------------------------------------------------------- + +TESTSUITE_INIT + call atlas_library%initialise() +END_TESTSUITE_INIT + +! ----------------------------------------------------------------------------- + +TESTSUITE_FINALIZE + call atlas_library%finalise() +END_TESTSUITE_FINALIZE + +TEST( test_resitribution ) +use atlas_module +use atlas_redistribution_module + +implicit none +type(atlas_StructuredGrid) :: grid +type(atlas_functionspace_StructuredColumns) :: fspace1, fspace2 +type(atlas_Redistribution) :: redist +type(c_ptr) :: cptr +grid = atlas_StructuredGrid("O16") +fspace1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions")) +fspace2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) + +redist = atlas_Redistribution(fspace1, fspace2) + +call redist%final() +call fspace2%final() +call fspace1%final() +call grid%final() +END_TEST + +! ----------------------------------------------------------------------------- + +END_TESTSUITE + From ad7cd24a8a0cdb8fdcca42ae3ae8143e598090e5 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Thu, 2 Nov 2023 11:23:34 +0100 Subject: [PATCH 03/16] default to RedistributeGeneric if nothing is provided in the configuration --- src/atlas/redistribution/detail/RedistributionInterface.cc | 4 +++- src/atlas_f/redistribution/atlas_Redistribution_module.F90 | 1 - src/tests/redistribution/fctest_redistribution.F90 | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc index ac010842c..7e5da6547 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.cc +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -29,7 +29,9 @@ detail::RedistributionImpl* atlas__Redistribution__new__config( const eckit::Configuration* config) { ATLAS_ASSERT(config != nullptr); std::string type; - config->get("type", type); + if (!config->get("type", type)) { + type = "RedistributeGeneric"; + }; auto redist = redistribution::detail::RedistributionImplFactory::build(type); redist->setup(fspace1, fspace2); return redist; diff --git a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 index c67d1a3d4..affb2828b 100644 --- a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 +++ b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 @@ -84,7 +84,6 @@ function ctor_create( fspace1, fspace2, redist_name ) result(this) type(atlas_Redistribution) :: this type(atlas_Config) :: config config = empty_config() - call config%set("type", "RedistributeGeneric") if (present(redist_name)) call config%set("type", redist_name) call this%reset_c_ptr( atlas__Redistribution__new__config(fspace1%CPTR_PGIBUG_A, fspace2%CPTR_PGIBUG_A, config%CPTR_PGIBUG_B) ) call config%final() diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index dfa02a29e..583587183 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -50,7 +50,7 @@ module fcta_Redistribution_fxt type(atlas_Redistribution) :: redist type(c_ptr) :: cptr grid = atlas_StructuredGrid("O16") -fspace1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions")) +fspace1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) fspace2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) redist = atlas_Redistribution(fspace1, fspace2) From d25aff8016f781cc8413a73a8f2eac64221575e8 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Thu, 2 Nov 2023 11:33:08 +0100 Subject: [PATCH 04/16] use static name from a redistribution factory --- src/atlas/redistribution/detail/RedistributionInterface.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc index 7e5da6547..b3faa28f9 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.cc +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -10,6 +10,7 @@ #include +#include "RedistributeGeneric.h" #include "RedistributionImpl.h" #include "RedistributionInterface.h" @@ -28,10 +29,8 @@ detail::RedistributionImpl* atlas__Redistribution__new__config( const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2, const eckit::Configuration* config) { ATLAS_ASSERT(config != nullptr); - std::string type; - if (!config->get("type", type)) { - type = "RedistributeGeneric"; - }; + std::string type = detail::RedistributeGeneric::static_type(); + config->get("type", type); auto redist = redistribution::detail::RedistributionImplFactory::build(type); redist->setup(fspace1, fspace2); return redist; From 7704a12b7f6bf25afbae4a6776584c053437f7db Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Thu, 2 Nov 2023 11:38:16 +0100 Subject: [PATCH 05/16] code coverage --- src/tests/redistribution/fctest_redistribution.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index 583587183..84042ce57 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -47,14 +47,16 @@ module fcta_Redistribution_fxt implicit none type(atlas_StructuredGrid) :: grid type(atlas_functionspace_StructuredColumns) :: fspace1, fspace2 -type(atlas_Redistribution) :: redist +type(atlas_Redistribution) :: redist, redist_hlp type(c_ptr) :: cptr grid = atlas_StructuredGrid("O16") fspace1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) fspace2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) redist = atlas_Redistribution(fspace1, fspace2) +redist_hlp = atlas_Redistribution(redist%c_ptr()) +call redist_hlp%final() call redist%final() call fspace2%final() call fspace1%final() From 94a63641fce049d5020cd208d6de1ffd225828a6 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Thu, 2 Nov 2023 16:19:03 +0100 Subject: [PATCH 06/16] extend the unit test for Fortran API Redistribution (setup works, exe runtime error) --- .../detail/RedistributionInterface.cc | 16 ++++++++ .../detail/RedistributionInterface.h | 20 +++++++-- .../atlas_Redistribution_module.F90 | 40 ++++++++++++++---- .../redistribution/fctest_redistribution.F90 | 41 +++++++++++++++---- 4 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc index b3faa28f9..98cb1ee19 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.cc +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -36,6 +36,22 @@ detail::RedistributionImpl* atlas__Redistribution__new__config( return redist; } +void atlas__Redistribution__execute( + const detail::RedistributionImpl* This, const Field* field_1, Field* field_2) { + printf("redist execute"); + This->execute(*field_1, *field_2); +} + +const FunctionSpace* atlas__Redistribution__source( + const detail::RedistributionImpl* This) { + return &This->source(); +} + +const FunctionSpace* atlas__Redistribution__target( + const detail::RedistributionImpl* This) { + return &This->target(); +} + } diff --git a/src/atlas/redistribution/detail/RedistributionInterface.h b/src/atlas/redistribution/detail/RedistributionInterface.h index e1fe3504c..62013dec8 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.h +++ b/src/atlas/redistribution/detail/RedistributionInterface.h @@ -15,7 +15,11 @@ class Configuration; namespace atlas { namespace functionspace{ -class FunctionSpaceImpl; +class FunctionSpace; +} +namespace field{ +class Field; +class FieldSet; } } // namespace atlas @@ -23,17 +27,27 @@ namespace atlas { namespace redistribution { namespace detail { class RedistributionImpl; -} // ------------------------------------------------------------------- // C wrapper interfaces to C++ routines extern "C" { -detail::RedistributionImpl* atlas__Redistribution__new__config( +RedistributionImpl* atlas__Redistribution__new__config( const functionspace::FunctionSpaceImpl* fspace1, const functionspace::FunctionSpaceImpl* fspace2, const eckit::Configuration* config); +void atlas__Redistribution__execute( + const RedistributionImpl* This, const Field* field_1, Field* field_2); + +const FunctionSpace* atlas__Redistribution__source( + const RedistributionImpl* This); + +const FunctionSpace* atlas__Redistribution__target( + const RedistributionImpl* This); + } + +} // namespace detail } // namespace redistribution } // namespace atlas diff --git a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 index affb2828b..054ba1115 100644 --- a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 +++ b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 @@ -21,26 +21,27 @@ module atlas_Redistribution_module private -!----------------------------- -! atlas_Redistribution ! -!----------------------------- - - !------------------------------------------------------------------------------ TYPE, extends(fckit_owned_object) :: atlas_Redistribution ! Purpose : ! ------- -! *Redistribution* : Object passed from atlas to inspect redistribution +! *atlas_Redistribution* : Object passed from atlas to inspect redistribution ! Methods : ! ------- ! Author : ! ------ +! October-2023 Slavko Brdar *ECMWF* +! August-2015 Willem Deconinck *ECMWF* !------------------------------------------------------------------------------ contains + + procedure, public :: execute => atlas_Redistribution__execute + procedure, public :: source => atlas_Redistribution__source + procedure, public :: target => atlas_Redistribution__target #if FCKIT_FINAL_NOT_INHERITING final :: atlas_Redistribution__final_auto @@ -77,7 +78,7 @@ function ctor_cptr( cptr ) result(this) call this%return() end function -function ctor_create( fspace1, fspace2, redist_name ) result(this) +function ctor_create(fspace1, fspace2, redist_name) result(this) use atlas_redistribution_c_binding class(atlas_FunctionSpace), intent(in) :: fspace1, fspace2 character(len=*), intent(in), optional :: redist_name @@ -90,6 +91,31 @@ function ctor_create( fspace1, fspace2, redist_name ) result(this) call this%return() end function +subroutine atlas_Redistribution__execute(this, field_1, field_2) + use atlas_redistribution_c_binding + use atlas_Field_module + class(atlas_Redistribution), intent(in) :: this + type(atlas_Field), intent(in) :: field_1 + type(atlas_Field), intent(out) :: field_2 + call atlas__Redistribution__execute(this%CPTR_PGIBUG_A, field_1%CPTR_PGIBUG_A, field_2%CPTR_PGIBUG_A) +end subroutine + +function atlas_Redistribution__source(this) result(fspace) + use atlas_redistribution_c_binding + class(atlas_Redistribution), intent(in) :: this + type(atlas_FunctionSpace) :: fspace + call fspace%reset_c_ptr(atlas__Redistribution__source(this%CPTR_PGIBUG_A)) + call fspace%return() +end function + +function atlas_Redistribution__target(this) result(fspace) + use atlas_redistribution_c_binding + class(atlas_Redistribution), intent(in) :: this + type(atlas_FunctionSpace) :: fspace + call fspace%reset_c_ptr(atlas__Redistribution__target(this%CPTR_PGIBUG_A)) + call fspace%return() +end function + ! ---------------------------------------------------------------------------------------- #if FCKIT_FINAL_NOT_INHERITING diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index 84042ce57..35894a803 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -46,20 +46,45 @@ module fcta_Redistribution_fxt implicit none type(atlas_StructuredGrid) :: grid -type(atlas_functionspace_StructuredColumns) :: fspace1, fspace2 +type(atlas_FunctionSpace) :: fspace_1, fspace_2, fspace_hlp +!type(atlas_functionspace_StructuredColumns) :: fspace_1, fspace_2 type(atlas_Redistribution) :: redist, redist_hlp -type(c_ptr) :: cptr -grid = atlas_StructuredGrid("O16") -fspace1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) -fspace2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) +type(atlas_Field) :: field_1, field_2 +real(c_double), pointer :: field_1v(:), field_2v(:) -redist = atlas_Redistribution(fspace1, fspace2) +grid = atlas_StructuredGrid("O8") +fspace_1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) +fspace_2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) + +redist = atlas_Redistribution(fspace_1, fspace_2) redist_hlp = atlas_Redistribution(redist%c_ptr()) +fspace_hlp = redist%source() +fspace_hlp = redist%target() + +field_1 = fspace_1%create_field(kind=atlas_real(c_double)) +field_2 = fspace_2%create_field(kind=atlas_real(c_double)) + +call field_1%data(field_1v) +field_1v = 1._c_double +call field_2%data(field_2v) +field_2v = 2._c_double + +print *, "fields done" + +!call redist%execute(field_1, field_2) + +print *, "redist exe done" + +call field_2%data(field_2v) +call field_2%halo_exchange() +!FCTEST_CHECK(all(field_2v == 1.)) +call field_2%final() +call field_1%final() call redist_hlp%final() call redist%final() -call fspace2%final() -call fspace1%final() +call fspace_2%final() +call fspace_1%final() call grid%final() END_TEST From 70f56265cd65c985c0c4a31218603078e5a750b0 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Thu, 2 Nov 2023 17:38:14 +0100 Subject: [PATCH 07/16] protect fortran test with HAVE_FORTRAN --- src/tests/redistribution/CMakeLists.txt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/tests/redistribution/CMakeLists.txt b/src/tests/redistribution/CMakeLists.txt index e188b2d8b..904fcadcd 100644 --- a/src/tests/redistribution/CMakeLists.txt +++ b/src/tests/redistribution/CMakeLists.txt @@ -7,14 +7,16 @@ if( atlas_HAVE_ATLAS_FUNCTIONSPACE ) -add_fctest( TARGET atlas_fctest_redistribution - MPI 4 - CONDITION eckit_HAVE_MPI - LINKER_LANGUAGE Fortran - SOURCES fctest_redistribution.F90 - LIBS atlas_f - ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} -) +if( HAVE_FORTRAN ) + add_fctest( TARGET atlas_fctest_redistribution + MPI 4 + CONDITION eckit_HAVE_MPI + LINKER_LANGUAGE Fortran + SOURCES fctest_redistribution.F90 + LIBS atlas_f + ENVIRONMENT ${ATLAS_TEST_ENVIRONMENT} + ) +endif() ecbuild_add_test( TARGET atlas_test_redistribution_structured SOURCES test_redistribution_structured.cc From 3a526712fc40f47764e6b4d8ae32a94830c9fac9 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Thu, 2 Nov 2023 17:48:22 +0100 Subject: [PATCH 08/16] tidy up (still runtime error on redistribute%execute) --- .../atlas_Redistribution_module.F90 | 2 +- .../redistribution/fctest_redistribution.F90 | 21 +++++++------------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 index 054ba1115..e6e188b55 100644 --- a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 +++ b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 @@ -96,7 +96,7 @@ subroutine atlas_Redistribution__execute(this, field_1, field_2) use atlas_Field_module class(atlas_Redistribution), intent(in) :: this type(atlas_Field), intent(in) :: field_1 - type(atlas_Field), intent(out) :: field_2 + type(atlas_Field), intent(inout) :: field_2 call atlas__Redistribution__execute(this%CPTR_PGIBUG_A, field_1%CPTR_PGIBUG_A, field_2%CPTR_PGIBUG_A) end subroutine diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index 35894a803..c954ac96a 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -46,11 +46,10 @@ module fcta_Redistribution_fxt implicit none type(atlas_StructuredGrid) :: grid -type(atlas_FunctionSpace) :: fspace_1, fspace_2, fspace_hlp -!type(atlas_functionspace_StructuredColumns) :: fspace_1, fspace_2 +type(atlas_functionspace_StructuredColumns) :: fspace_1, fspace_2, fspace_hlp type(atlas_Redistribution) :: redist, redist_hlp type(atlas_Field) :: field_1, field_2 -real(c_double), pointer :: field_1v(:), field_2v(:) +real(c_float), pointer :: field_1v(:), field_2v(:) grid = atlas_StructuredGrid("O8") fspace_1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) @@ -61,23 +60,19 @@ module fcta_Redistribution_fxt fspace_hlp = redist%source() fspace_hlp = redist%target() -field_1 = fspace_1%create_field(kind=atlas_real(c_double)) -field_2 = fspace_2%create_field(kind=atlas_real(c_double)) +field_1 = fspace_1%create_field(atlas_real(c_float)) +field_2 = fspace_2%create_field(atlas_real(c_float)) call field_1%data(field_1v) -field_1v = 1._c_double +field_1v = 1._c_float call field_2%data(field_2v) -field_2v = 2._c_double +field_2v = 2._c_float -print *, "fields done" - -!call redist%execute(field_1, field_2) - -print *, "redist exe done" +call redist%execute(field_1, field_2) call field_2%data(field_2v) call field_2%halo_exchange() -!FCTEST_CHECK(all(field_2v == 1.)) +FCTEST_CHECK(all(field_2v == 1.)) call field_2%final() call field_1%final() From 806b19fa7329964a4d516d543721ecc41adc6a3e Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Wed, 8 Nov 2023 12:49:22 +0100 Subject: [PATCH 09/16] 1) fix Fortran API for Redistribution; 2) improve unit test (with Willem) --- src/atlas/redistribution/Redistribution.cc | 4 +-- .../detail/RedistributeGeneric.cc | 32 ++++++++++--------- .../detail/RedistributeGeneric.h | 11 ++++--- .../detail/RedistributeStructuredColumns.cc | 23 +++++++------ .../detail/RedistributeStructuredColumns.h | 10 +++--- .../detail/RedistributionImpl.h | 12 ++++--- .../detail/RedistributionInterface.cc | 13 ++++---- .../detail/RedistributionInterface.h | 12 +++---- .../atlas_Redistribution_module.F90 | 4 +-- .../redistribution/fctest_redistribution.F90 | 2 +- 10 files changed, 67 insertions(+), 56 deletions(-) diff --git a/src/atlas/redistribution/Redistribution.cc b/src/atlas/redistribution/Redistribution.cc index 1c9d9a4f6..96bc1fb77 100644 --- a/src/atlas/redistribution/Redistribution.cc +++ b/src/atlas/redistribution/Redistribution.cc @@ -31,12 +31,12 @@ Redistribution::Redistribution(const FunctionSpace& sourceFunctionSpace, const F }()) {} void Redistribution::execute(const Field& source, Field& target) const { - get()->execute(source, target); + get()->execute(source.get(), target.get()); return; } void Redistribution::execute(const FieldSet& source, FieldSet& target) const { - get()->execute(source, target); + get()->execute(source.get(), target.get()); return; } diff --git a/src/atlas/redistribution/detail/RedistributeGeneric.cc b/src/atlas/redistribution/detail/RedistributeGeneric.cc index 9e86fff15..08cd48961 100644 --- a/src/atlas/redistribution/detail/RedistributeGeneric.cc +++ b/src/atlas/redistribution/detail/RedistributeGeneric.cc @@ -282,7 +282,9 @@ void RedistributeGeneric::do_setup() { std::tie(targetLocalIdx_, targetDisps_) = getUidIntersection(mpi_comm_, targetUidVec, sourceGlobalUids, sourceGlobalDisps); } -void RedistributeGeneric::execute(const Field& sourceField, Field& targetField) const { +void RedistributeGeneric::execute(const field::FieldImpl* sf, field::FieldImpl* tf) const { + const field::FieldImpl& sourceField = *sf; + field::FieldImpl& targetField = *tf; //Check functionspaces match. ATLAS_ASSERT(sourceField.functionspace().type() == source().type()); ATLAS_ASSERT(targetField.functionspace().type() == target().type()); @@ -299,23 +301,23 @@ void RedistributeGeneric::execute(const Field& sourceField, Field& targetField) } // Perform redistribution. - do_execute(sourceField, targetField); + do_execute(sf, tf); } -void RedistributeGeneric::execute(const FieldSet& sourceFieldSet, FieldSet& targetFieldSet) const { +void RedistributeGeneric::execute(const field::FieldSetImpl* sourceFieldSet, field::FieldSetImpl* targetFieldSet) const { // Check field set sizes match. - ATLAS_ASSERT(sourceFieldSet.size() == targetFieldSet.size()); + ATLAS_ASSERT(sourceFieldSet->size() == targetFieldSet->size()); // Redistribute fields. - for (idx_t i = 0; i < sourceFieldSet.size(); ++i) { - execute(sourceFieldSet[i], targetFieldSet[i]); + for (idx_t i = 0; i < sourceFieldSet->size(); ++i) { + execute(&sourceFieldSet[i], &targetFieldSet[i]); } } // Determine datatype. -void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { +void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field::FieldImpl* targetField) const { // Available datatypes defined in array/LocalView.cc - switch (sourceField.datatype().kind()) { + switch (sourceField->datatype().kind()) { case array::DataType::KIND_REAL64: { return do_execute(sourceField, targetField); } @@ -329,16 +331,16 @@ void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetFiel return do_execute(sourceField, targetField); } default: { - ATLAS_THROW_EXCEPTION("No implementation for data type " + sourceField.datatype().str()); + ATLAS_THROW_EXCEPTION("No implementation for data type " + sourceField->datatype().str()); } } } // Determine rank. template -void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { +void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field::FieldImpl* targetField) const { // Available ranks defined in array/LocalView.cc - switch (sourceField.rank()) { + switch (sourceField->rank()) { case 1: { return do_execute(sourceField, targetField); } @@ -367,17 +369,17 @@ void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetFiel return do_execute(sourceField, targetField); } default: { - ATLAS_THROW_EXCEPTION("No implementation for rank " + std::to_string(sourceField.rank())); + ATLAS_THROW_EXCEPTION("No implementation for rank " + std::to_string(sourceField->rank())); } } } // Perform redistribution. template -void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { +void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field::FieldImpl* targetField) const { // Get array views. - auto sourceView = array::make_view(sourceField); - auto targetView = array::make_view(targetField); + auto sourceView = array::make_view(*sourceField); + auto targetView = array::make_view(*targetField); const auto& comm = mpi::comm(mpi_comm_); auto mpi_size = comm.size(); diff --git a/src/atlas/redistribution/detail/RedistributeGeneric.h b/src/atlas/redistribution/detail/RedistributeGeneric.h index a650fd02c..f5d13815a 100644 --- a/src/atlas/redistribution/detail/RedistributeGeneric.h +++ b/src/atlas/redistribution/detail/RedistributeGeneric.h @@ -9,6 +9,7 @@ #include +#include "atlas/field/detail/FieldImpl.h" #include "atlas/redistribution/detail/RedistributionImpl.h" namespace atlas { @@ -23,19 +24,19 @@ class RedistributeGeneric : public RedistributionImpl { void do_setup() override; - void execute(const Field& source, Field& target) const override; + void execute(const field::FieldImpl* source, field::FieldImpl* target) const override; - void execute(const FieldSet& source, FieldSet& target) const override; + void execute(const field::FieldSetImpl* source, field::FieldSetImpl* target) const override; private: // Determine datatype. - void do_execute(const Field& source, Field& target) const; + void do_execute(const field::FieldImpl* source, field::FieldImpl* target) const; // Determine rank. template - void do_execute(const Field& source, Field& target) const; + void do_execute(const field::FieldImpl* source, field::FieldImpl* target) const; // Perform redistribution. template - void do_execute(const Field& source, Field& target) const; + void do_execute(const field::FieldImpl* source, field::FieldImpl* target) const; // Local indices to send to each PE std::vector sourceLocalIdx_{}; diff --git a/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc b/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc index 3ef241fd7..60096e02f 100644 --- a/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc +++ b/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc @@ -127,7 +127,9 @@ void RedistributeStructuredColumns::do_setup() { return; } -void RedistributeStructuredColumns::execute(const Field& sourceField, Field& targetField) const { +void RedistributeStructuredColumns::execute(const field::FieldImpl* sf, field::FieldImpl* tf) const { + const field::FieldImpl& sourceField = *sf; + field::FieldImpl& targetField = *tf; // Assert that fields are defined on StructuredColumns. ATLAS_ASSERT(functionspace::StructuredColumns(sourceField.functionspace())); ATLAS_ASSERT(functionspace::StructuredColumns(targetField.functionspace())); @@ -165,15 +167,18 @@ void RedistributeStructuredColumns::execute(const Field& sourceField, Field& tar return; } -void RedistributeStructuredColumns::execute(const FieldSet& sourceFieldSet, FieldSet& targetFieldSet) const { +void RedistributeStructuredColumns::execute(const field::FieldSetImpl* sourceFieldSet, field::FieldSetImpl* targetFieldSet) const { // Check that both FieldSets are the same size. - ATLAS_ASSERT(sourceFieldSet.size() == targetFieldSet.size()); + ATLAS_ASSERT(sourceFieldSet->size() == targetFieldSet->size()); - auto targetFieldSetIt = targetFieldSet.begin(); - std::for_each(sourceFieldSet.cbegin(), sourceFieldSet.cend(), [&](const Field& sourceField) { - execute(sourceField, *targetFieldSetIt++); - return; - }); + auto targetFieldSetIt = targetFieldSet->begin(); + for (int i = 0; i < sourceFieldSet->size(); i++) { + execute(&sourceFieldSet[i], &targetFieldSet[i]); + } + //std::for_each(sourceFieldSet->cbegin(), sourceFieldSet->cend(), [&](const field::FieldImpl* sourceField) { + // execute(sourceField, targetFieldSetIt++); + // return; + //}); return; } @@ -183,7 +188,7 @@ void RedistributeStructuredColumns::execute(const FieldSet& sourceFieldSet, Fiel //======================================================================== template -void RedistributeStructuredColumns::do_execute(const Field& sourceField, Field& targetField) const { +void RedistributeStructuredColumns::do_execute(const field::FieldImpl& sourceField, field::FieldImpl& targetField) const { // Make Atlas view objects. const auto sourceView = array::make_view(sourceField); auto targetView = array::make_view(targetField); diff --git a/src/atlas/redistribution/detail/RedistributeStructuredColumns.h b/src/atlas/redistribution/detail/RedistributeStructuredColumns.h index 7972078b8..a4dd5b345 100644 --- a/src/atlas/redistribution/detail/RedistributeStructuredColumns.h +++ b/src/atlas/redistribution/detail/RedistributeStructuredColumns.h @@ -15,8 +15,8 @@ namespace atlas { -class Field; -class FieldSet; +class FieldImpl; +class FieldSetImpl; class FunctionSpace; namespace functionspace { @@ -63,7 +63,7 @@ class RedistributeStructuredColumns : public RedistributionImpl { /// /// \param[in] source input field matching sourceFunctionSpace. /// \param[out] target output field matching targetFunctionSpace. - void execute(const Field& source, Field& target) const override; + void execute(const field::FieldImpl* source, field::FieldImpl* target) const override; /// \brief Redistributes source field set to target fields set. /// @@ -72,12 +72,12 @@ class RedistributeStructuredColumns : public RedistributionImpl { /// /// \param[in] source input field set. /// \param[out] target output field set. - void execute(const FieldSet& source, FieldSet& target) const override; + void execute(const field::FieldSetImpl* source, field::FieldSetImpl* target) const override; private: // Generic execute call to handle different field types. template - void do_execute(const Field& source, Field& target) const; + void do_execute(const field::FieldImpl& source, field::FieldImpl& target) const; // FunctionSpaces recast to StructuredColumns. functionspace::StructuredColumns source_; diff --git a/src/atlas/redistribution/detail/RedistributionImpl.h b/src/atlas/redistribution/detail/RedistributionImpl.h index bcdefa3d8..bcb8a4d60 100644 --- a/src/atlas/redistribution/detail/RedistributionImpl.h +++ b/src/atlas/redistribution/detail/RedistributionImpl.h @@ -11,9 +11,13 @@ #include "atlas/util/Object.h" namespace atlas { -class Field; -class FieldSet; + namespace field { +class FieldImpl; +class FieldSetImpl; + } + namespace functionspace { class FunctionSpace; + } } // namespace atlas namespace atlas { @@ -42,10 +46,10 @@ class RedistributionImpl : public util::Object { virtual std::string type() const = 0; /// \brief Maps source field to target field. - virtual void execute(const Field& source, Field& target) const = 0; + virtual void execute(const field::FieldImpl* source, field::FieldImpl* target) const = 0; /// \brief Maps source field set to target field set. - virtual void execute(const FieldSet& source, FieldSet& target) const = 0; + virtual void execute(const field::FieldSetImpl* source, field::FieldSetImpl* target) const = 0; /// \brief Get const reference to source function space. const FunctionSpace& source() const; diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc index 98cb1ee19..e5b2613a7 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.cc +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -37,19 +37,18 @@ detail::RedistributionImpl* atlas__Redistribution__new__config( } void atlas__Redistribution__execute( - const detail::RedistributionImpl* This, const Field* field_1, Field* field_2) { - printf("redist execute"); - This->execute(*field_1, *field_2); + const detail::RedistributionImpl* This, const field::FieldImpl* field_1, field::FieldImpl* field_2) { + This->execute(field_1, field_2); } -const FunctionSpace* atlas__Redistribution__source( +const functionspace::FunctionSpaceImpl* atlas__Redistribution__source( const detail::RedistributionImpl* This) { - return &This->source(); + return This->source().get(); } -const FunctionSpace* atlas__Redistribution__target( +const functionspace::FunctionSpaceImpl* atlas__Redistribution__target( const detail::RedistributionImpl* This) { - return &This->target(); + return This->target().get(); } } diff --git a/src/atlas/redistribution/detail/RedistributionInterface.h b/src/atlas/redistribution/detail/RedistributionInterface.h index 62013dec8..25d8d2078 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.h +++ b/src/atlas/redistribution/detail/RedistributionInterface.h @@ -15,11 +15,11 @@ class Configuration; namespace atlas { namespace functionspace{ -class FunctionSpace; +class FunctionSpaceImpl; } namespace field{ -class Field; -class FieldSet; +class FieldImpl; +class FieldSetImpl; } } // namespace atlas @@ -37,12 +37,12 @@ RedistributionImpl* atlas__Redistribution__new__config( const eckit::Configuration* config); void atlas__Redistribution__execute( - const RedistributionImpl* This, const Field* field_1, Field* field_2); + const RedistributionImpl* This, const field::FieldImpl* field_1, field::FieldImpl* field_2); -const FunctionSpace* atlas__Redistribution__source( +const functionspace::FunctionSpaceImpl* atlas__Redistribution__source( const RedistributionImpl* This); -const FunctionSpace* atlas__Redistribution__target( +const functionspace::FunctionSpaceImpl* atlas__Redistribution__target( const RedistributionImpl* This); } diff --git a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 index e6e188b55..1461e4c76 100644 --- a/src/atlas_f/redistribution/atlas_Redistribution_module.F90 +++ b/src/atlas_f/redistribution/atlas_Redistribution_module.F90 @@ -95,8 +95,8 @@ subroutine atlas_Redistribution__execute(this, field_1, field_2) use atlas_redistribution_c_binding use atlas_Field_module class(atlas_Redistribution), intent(in) :: this - type(atlas_Field), intent(in) :: field_1 - type(atlas_Field), intent(inout) :: field_2 + class(atlas_Field), intent(in) :: field_1 + class(atlas_Field), intent(inout) :: field_2 call atlas__Redistribution__execute(this%CPTR_PGIBUG_A, field_1%CPTR_PGIBUG_A, field_2%CPTR_PGIBUG_A) end subroutine diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index c954ac96a..995918adc 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -40,7 +40,7 @@ module fcta_Redistribution_fxt call atlas_library%finalise() END_TESTSUITE_FINALIZE -TEST( test_resitribution ) +TEST( test_redistribution ) use atlas_module use atlas_redistribution_module From 648fb47703bbcfefb5cc566ec4b4a4cb75e6ce20 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Wed, 8 Nov 2023 14:31:05 +0100 Subject: [PATCH 10/16] fix C++ unit test --- src/atlas/redistribution/Redistribution.cc | 4 ++-- .../detail/RedistributeGeneric.cc | 22 +++++++++---------- .../detail/RedistributeGeneric.h | 10 ++++----- .../detail/RedistributeStructuredColumns.cc | 19 ++++++---------- .../detail/RedistributeStructuredColumns.h | 6 ++--- .../detail/RedistributionImpl.h | 8 +++---- .../detail/RedistributionInterface.cc | 9 ++++++-- .../detail/RedistributionInterface.h | 10 ++++----- 8 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/atlas/redistribution/Redistribution.cc b/src/atlas/redistribution/Redistribution.cc index 96bc1fb77..1c9d9a4f6 100644 --- a/src/atlas/redistribution/Redistribution.cc +++ b/src/atlas/redistribution/Redistribution.cc @@ -31,12 +31,12 @@ Redistribution::Redistribution(const FunctionSpace& sourceFunctionSpace, const F }()) {} void Redistribution::execute(const Field& source, Field& target) const { - get()->execute(source.get(), target.get()); + get()->execute(source, target); return; } void Redistribution::execute(const FieldSet& source, FieldSet& target) const { - get()->execute(source.get(), target.get()); + get()->execute(source, target); return; } diff --git a/src/atlas/redistribution/detail/RedistributeGeneric.cc b/src/atlas/redistribution/detail/RedistributeGeneric.cc index 08cd48961..d59748eb5 100644 --- a/src/atlas/redistribution/detail/RedistributeGeneric.cc +++ b/src/atlas/redistribution/detail/RedistributeGeneric.cc @@ -282,9 +282,7 @@ void RedistributeGeneric::do_setup() { std::tie(targetLocalIdx_, targetDisps_) = getUidIntersection(mpi_comm_, targetUidVec, sourceGlobalUids, sourceGlobalDisps); } -void RedistributeGeneric::execute(const field::FieldImpl* sf, field::FieldImpl* tf) const { - const field::FieldImpl& sourceField = *sf; - field::FieldImpl& targetField = *tf; +void RedistributeGeneric::execute(const Field& sourceField, Field& targetField) const { //Check functionspaces match. ATLAS_ASSERT(sourceField.functionspace().type() == source().type()); ATLAS_ASSERT(targetField.functionspace().type() == target().type()); @@ -301,21 +299,23 @@ void RedistributeGeneric::execute(const field::FieldImpl* sf, field::FieldImpl* } // Perform redistribution. - do_execute(sf, tf); + do_execute(sourceField, targetField); } -void RedistributeGeneric::execute(const field::FieldSetImpl* sourceFieldSet, field::FieldSetImpl* targetFieldSet) const { +void RedistributeGeneric::execute(const FieldSet& sourceFieldSet, FieldSet& targetFieldSet) const { // Check field set sizes match. ATLAS_ASSERT(sourceFieldSet->size() == targetFieldSet->size()); // Redistribute fields. - for (idx_t i = 0; i < sourceFieldSet->size(); ++i) { - execute(&sourceFieldSet[i], &targetFieldSet[i]); - } + auto targetFieldSetIt = targetFieldSet->begin(); + std::for_each(sourceFieldSet->cbegin(), sourceFieldSet->cend(), [&](const Field& sourceField) { + execute(sourceField, *targetFieldSetIt++); + return; + }); } // Determine datatype. -void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field::FieldImpl* targetField) const { +void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { // Available datatypes defined in array/LocalView.cc switch (sourceField->datatype().kind()) { case array::DataType::KIND_REAL64: { @@ -338,7 +338,7 @@ void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field: // Determine rank. template -void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field::FieldImpl* targetField) const { +void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { // Available ranks defined in array/LocalView.cc switch (sourceField->rank()) { case 1: { @@ -376,7 +376,7 @@ void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field: // Perform redistribution. template -void RedistributeGeneric::do_execute(const field::FieldImpl* sourceField, field::FieldImpl* targetField) const { +void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { // Get array views. auto sourceView = array::make_view(*sourceField); auto targetView = array::make_view(*targetField); diff --git a/src/atlas/redistribution/detail/RedistributeGeneric.h b/src/atlas/redistribution/detail/RedistributeGeneric.h index f5d13815a..1878aad67 100644 --- a/src/atlas/redistribution/detail/RedistributeGeneric.h +++ b/src/atlas/redistribution/detail/RedistributeGeneric.h @@ -24,19 +24,19 @@ class RedistributeGeneric : public RedistributionImpl { void do_setup() override; - void execute(const field::FieldImpl* source, field::FieldImpl* target) const override; + void execute(const Field& source, Field& target) const override; - void execute(const field::FieldSetImpl* source, field::FieldSetImpl* target) const override; + void execute(const FieldSet& source, FieldSet& target) const override; private: // Determine datatype. - void do_execute(const field::FieldImpl* source, field::FieldImpl* target) const; + void do_execute(const Field& source, Field& target) const; // Determine rank. template - void do_execute(const field::FieldImpl* source, field::FieldImpl* target) const; + void do_execute(const Field& source, Field& target) const; // Perform redistribution. template - void do_execute(const field::FieldImpl* source, field::FieldImpl* target) const; + void do_execute(const Field& source, Field& target) const; // Local indices to send to each PE std::vector sourceLocalIdx_{}; diff --git a/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc b/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc index 60096e02f..b8cfb10c6 100644 --- a/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc +++ b/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc @@ -127,9 +127,7 @@ void RedistributeStructuredColumns::do_setup() { return; } -void RedistributeStructuredColumns::execute(const field::FieldImpl* sf, field::FieldImpl* tf) const { - const field::FieldImpl& sourceField = *sf; - field::FieldImpl& targetField = *tf; +void RedistributeStructuredColumns::execute(const Field& sourceField, Field& targetField) const { // Assert that fields are defined on StructuredColumns. ATLAS_ASSERT(functionspace::StructuredColumns(sourceField.functionspace())); ATLAS_ASSERT(functionspace::StructuredColumns(targetField.functionspace())); @@ -167,18 +165,15 @@ void RedistributeStructuredColumns::execute(const field::FieldImpl* sf, field::F return; } -void RedistributeStructuredColumns::execute(const field::FieldSetImpl* sourceFieldSet, field::FieldSetImpl* targetFieldSet) const { +void RedistributeStructuredColumns::execute(const FieldSet& sourceFieldSet, FieldSet& targetFieldSet) const { // Check that both FieldSets are the same size. ATLAS_ASSERT(sourceFieldSet->size() == targetFieldSet->size()); auto targetFieldSetIt = targetFieldSet->begin(); - for (int i = 0; i < sourceFieldSet->size(); i++) { - execute(&sourceFieldSet[i], &targetFieldSet[i]); - } - //std::for_each(sourceFieldSet->cbegin(), sourceFieldSet->cend(), [&](const field::FieldImpl* sourceField) { - // execute(sourceField, targetFieldSetIt++); - // return; - //}); + std::for_each(sourceFieldSet->cbegin(), sourceFieldSet->cend(), [&](const Field& sourceField) { + execute(sourceField, *targetFieldSetIt++); + return; + }); return; } @@ -188,7 +183,7 @@ void RedistributeStructuredColumns::execute(const field::FieldSetImpl* sourceFie //======================================================================== template -void RedistributeStructuredColumns::do_execute(const field::FieldImpl& sourceField, field::FieldImpl& targetField) const { +void RedistributeStructuredColumns::do_execute(const Field& sourceField, Field& targetField) const { // Make Atlas view objects. const auto sourceView = array::make_view(sourceField); auto targetView = array::make_view(targetField); diff --git a/src/atlas/redistribution/detail/RedistributeStructuredColumns.h b/src/atlas/redistribution/detail/RedistributeStructuredColumns.h index a4dd5b345..dec63b14d 100644 --- a/src/atlas/redistribution/detail/RedistributeStructuredColumns.h +++ b/src/atlas/redistribution/detail/RedistributeStructuredColumns.h @@ -63,7 +63,7 @@ class RedistributeStructuredColumns : public RedistributionImpl { /// /// \param[in] source input field matching sourceFunctionSpace. /// \param[out] target output field matching targetFunctionSpace. - void execute(const field::FieldImpl* source, field::FieldImpl* target) const override; + void execute(const Field& source, Field& target) const override; /// \brief Redistributes source field set to target fields set. /// @@ -72,12 +72,12 @@ class RedistributeStructuredColumns : public RedistributionImpl { /// /// \param[in] source input field set. /// \param[out] target output field set. - void execute(const field::FieldSetImpl* source, field::FieldSetImpl* target) const override; + void execute(const FieldSet& source, FieldSet& target) const override; private: // Generic execute call to handle different field types. template - void do_execute(const field::FieldImpl& source, field::FieldImpl& target) const; + void do_execute(const Field& source, Field& target) const; // FunctionSpaces recast to StructuredColumns. functionspace::StructuredColumns source_; diff --git a/src/atlas/redistribution/detail/RedistributionImpl.h b/src/atlas/redistribution/detail/RedistributionImpl.h index bcb8a4d60..f1f94c5aa 100644 --- a/src/atlas/redistribution/detail/RedistributionImpl.h +++ b/src/atlas/redistribution/detail/RedistributionImpl.h @@ -12,8 +12,8 @@ namespace atlas { namespace field { -class FieldImpl; -class FieldSetImpl; +class Field; +class FieldSet; } namespace functionspace { class FunctionSpace; @@ -46,10 +46,10 @@ class RedistributionImpl : public util::Object { virtual std::string type() const = 0; /// \brief Maps source field to target field. - virtual void execute(const field::FieldImpl* source, field::FieldImpl* target) const = 0; + virtual void execute(const Field& source, Field& target) const = 0; /// \brief Maps source field set to target field set. - virtual void execute(const field::FieldSetImpl* source, field::FieldSetImpl* target) const = 0; + virtual void execute(const FieldSet& source, FieldSet& target) const = 0; /// \brief Get const reference to source function space. const FunctionSpace& source() const; diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc index e5b2613a7..0b66e2304 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.cc +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -14,6 +14,7 @@ #include "RedistributionImpl.h" #include "RedistributionInterface.h" +#include "atlas/functionspace/FunctionSpace.h" #include "atlas/redistribution/detail/RedistributionImplFactory.h" namespace atlas { @@ -32,13 +33,17 @@ detail::RedistributionImpl* atlas__Redistribution__new__config( std::string type = detail::RedistributeGeneric::static_type(); config->get("type", type); auto redist = redistribution::detail::RedistributionImplFactory::build(type); - redist->setup(fspace1, fspace2); + FunctionSpace fs1(fspace1); + FunctionSpace fs2(fspace2); + redist->setup(fs1, fs2); return redist; } void atlas__Redistribution__execute( const detail::RedistributionImpl* This, const field::FieldImpl* field_1, field::FieldImpl* field_2) { - This->execute(field_1, field_2); + Field f1(field_1); + Field f2(field_2); + This->execute(f1, f2); } const functionspace::FunctionSpaceImpl* atlas__Redistribution__source( diff --git a/src/atlas/redistribution/detail/RedistributionInterface.h b/src/atlas/redistribution/detail/RedistributionInterface.h index 25d8d2078..500e32c79 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.h +++ b/src/atlas/redistribution/detail/RedistributionInterface.h @@ -14,12 +14,12 @@ class Configuration; } namespace atlas { -namespace functionspace{ -class FunctionSpaceImpl; +namespace functionspace { +class FunctionSpace; } -namespace field{ -class FieldImpl; -class FieldSetImpl; +namespace field { +class Field; +class FieldSet; } } // namespace atlas From ec7ca9712dfcf357052f824f6d781ebb89aabb72 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Wed, 8 Nov 2023 15:44:55 +0100 Subject: [PATCH 11/16] use generic structures in Fortran --- src/tests/redistribution/fctest_redistribution.F90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index 995918adc..bc66f8771 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -45,13 +45,13 @@ module fcta_Redistribution_fxt use atlas_redistribution_module implicit none -type(atlas_StructuredGrid) :: grid -type(atlas_functionspace_StructuredColumns) :: fspace_1, fspace_2, fspace_hlp +type(atlas_Grid) :: grid +type(atlas_FunctionSpace) :: fspace_1, fspace_2, fspace_hlp type(atlas_Redistribution) :: redist, redist_hlp type(atlas_Field) :: field_1, field_2 real(c_float), pointer :: field_1v(:), field_2v(:) -grid = atlas_StructuredGrid("O8") +grid = atlas_Grid("O8") fspace_1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) fspace_2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) From 390eb0b9120cb1c42edf2c0dc7bd312b6ef230e1 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Wed, 8 Nov 2023 19:11:07 +0100 Subject: [PATCH 12/16] use parameter variable for atlas_Grid --- src/tests/redistribution/fctest_redistribution.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index bc66f8771..2e9387870 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -50,8 +50,9 @@ module fcta_Redistribution_fxt type(atlas_Redistribution) :: redist, redist_hlp type(atlas_Field) :: field_1, field_2 real(c_float), pointer :: field_1v(:), field_2v(:) +character(len=*), parameter :: gridname = "O8" -grid = atlas_Grid("O8") +grid = atlas_Grid(gridname) fspace_1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) fspace_2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) From fb0080bb53296c0a8f8a51cb281a7d4bca99b30e Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Wed, 8 Nov 2023 23:55:49 +0100 Subject: [PATCH 13/16] check also NodeColumns and EdgeColumns for Fortran API Redistribution --- .../redistribution/fctest_redistribution.F90 | 60 +++++++++++++++---- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index 2e9387870..2ef8aeaf9 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -40,30 +40,25 @@ module fcta_Redistribution_fxt call atlas_library%finalise() END_TESTSUITE_FINALIZE -TEST( test_redistribution ) +! ----------------------------------------------------------------------------- + +subroutine do_redistribute(fspace_1, fspace_2) use atlas_module use atlas_redistribution_module implicit none -type(atlas_Grid) :: grid -type(atlas_FunctionSpace) :: fspace_1, fspace_2, fspace_hlp + +type(atlas_FunctionSpace), intent(in) :: fspace_1, fspace_2 + +type(atlas_FunctionSpace) :: fspace_hlp type(atlas_Redistribution) :: redist, redist_hlp type(atlas_Field) :: field_1, field_2 real(c_float), pointer :: field_1v(:), field_2v(:) -character(len=*), parameter :: gridname = "O8" - -grid = atlas_Grid(gridname) -fspace_1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions"), halo=2) -fspace_2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) redist = atlas_Redistribution(fspace_1, fspace_2) -redist_hlp = atlas_Redistribution(redist%c_ptr()) -fspace_hlp = redist%source() -fspace_hlp = redist%target() field_1 = fspace_1%create_field(atlas_real(c_float)) field_2 = fspace_2%create_field(atlas_real(c_float)) - call field_1%data(field_1v) field_1v = 1._c_float call field_2%data(field_2v) @@ -75,10 +70,51 @@ module fcta_Redistribution_fxt call field_2%halo_exchange() FCTEST_CHECK(all(field_2v == 1.)) +! check access to source and target function spaces +redist_hlp = atlas_Redistribution(redist%c_ptr()) +fspace_hlp = redist%source() +fspace_hlp = redist%target() + call field_2%final() call field_1%final() call redist_hlp%final() call redist%final() +end subroutine do_redistribute + +! ----------------------------------------------------------------------------- + +TEST( test_redistribution ) +use atlas_module +use atlas_redistribution_module + +implicit none +type(atlas_Grid) :: grid +type(atlas_Mesh) :: mesh +type(atlas_MeshGenerator) :: meshgenerator +type(atlas_FunctionSpace) :: fspace_1, fspace_2 +type(atlas_Config) :: config +character(len=*), parameter :: gridname = "O8" + +config = atlas_Config() +call config%set("halo", 2) + +grid = atlas_Grid(gridname) +fspace_1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions")) +fspace_2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) +call do_redistribute(fspace_1, fspace_2) + +meshgenerator = atlas_MeshGenerator() +mesh = meshgenerator%generate(grid, atlas_Partitioner("equal_regions")) +fspace_1 = atlas_functionspace_NodeColumns(mesh) +mesh = meshgenerator%generate(grid, atlas_Partitioner("regular_bands")) +fspace_2 = atlas_functionspace_NodeColumns(mesh) +call do_redistribute(fspace_1, fspace_2) + +fspace_2 = atlas_functionspace_EdgeColumns(mesh) +mesh = meshgenerator%generate(grid, atlas_Partitioner("equal_regions")) +fspace_1 = atlas_functionspace_EdgeColumns(mesh) +call do_redistribute(fspace_1, fspace_2) + call fspace_2%final() call fspace_1%final() call grid%final() From 536daf25a820a4bb6cd9762141864b2903c3cac9 Mon Sep 17 00:00:00 2001 From: Slavko Brdar Date: Thu, 9 Nov 2023 12:14:47 +0000 Subject: [PATCH 14/16] workaround for intel compiler (tnx Willem) --- .../redistribution/fctest_redistribution.F90 | 74 ++++++++++--------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/src/tests/redistribution/fctest_redistribution.F90 b/src/tests/redistribution/fctest_redistribution.F90 index 2ef8aeaf9..a023f3e8e 100644 --- a/src/tests/redistribution/fctest_redistribution.F90 +++ b/src/tests/redistribution/fctest_redistribution.F90 @@ -20,39 +20,21 @@ module fcta_Redistribution_fxt use, intrinsic :: iso_c_binding implicit none character(len=1024) :: msg -contains - -end module - -! ----------------------------------------------------------------------------- - -TESTSUITE_WITH_FIXTURE(fcta_Redistribution,fcta_Redistribution_fxt) - -! ----------------------------------------------------------------------------- - -TESTSUITE_INIT - call atlas_library%initialise() -END_TESTSUITE_INIT - -! ----------------------------------------------------------------------------- - -TESTSUITE_FINALIZE - call atlas_library%finalise() -END_TESTSUITE_FINALIZE -! ----------------------------------------------------------------------------- +contains -subroutine do_redistribute(fspace_1, fspace_2) +function do_redistribute(fspace_1, fspace_2) result(field_2) use atlas_module use atlas_redistribution_module implicit none type(atlas_FunctionSpace), intent(in) :: fspace_1, fspace_2 +type(atlas_Field) :: field_2 type(atlas_FunctionSpace) :: fspace_hlp type(atlas_Redistribution) :: redist, redist_hlp -type(atlas_Field) :: field_1, field_2 +type(atlas_Field) :: field_1 !, field_2 real(c_float), pointer :: field_1v(:), field_2v(:) redist = atlas_Redistribution(fspace_1, fspace_2) @@ -68,52 +50,77 @@ subroutine do_redistribute(fspace_1, fspace_2) call field_2%data(field_2v) call field_2%halo_exchange() -FCTEST_CHECK(all(field_2v == 1.)) ! check access to source and target function spaces redist_hlp = atlas_Redistribution(redist%c_ptr()) fspace_hlp = redist%source() fspace_hlp = redist%target() -call field_2%final() call field_1%final() call redist_hlp%final() call redist%final() -end subroutine do_redistribute +end function do_redistribute + +end module + +! ----------------------------------------------------------------------------- + +TESTSUITE(fcta_Redistribution) +!TESTSUITE_WITH_FIXTURE(fcta_Redistribution,fcta_Redistribution_fxt) + +! ----------------------------------------------------------------------------- + +TESTSUITE_INIT + use atlas_module + call atlas_library%initialise() +END_TESTSUITE_INIT + +! ----------------------------------------------------------------------------- + +TESTSUITE_FINALIZE + use atlas_module + call atlas_library%finalise() +END_TESTSUITE_FINALIZE ! ----------------------------------------------------------------------------- TEST( test_redistribution ) use atlas_module +use fcta_Redistribution_fxt use atlas_redistribution_module implicit none + type(atlas_Grid) :: grid type(atlas_Mesh) :: mesh type(atlas_MeshGenerator) :: meshgenerator type(atlas_FunctionSpace) :: fspace_1, fspace_2 -type(atlas_Config) :: config -character(len=*), parameter :: gridname = "O8" +type(atlas_Field) :: field +real(c_float) , pointer :: field_v(:) -config = atlas_Config() -call config%set("halo", 2) +grid = atlas_Grid("O8") -grid = atlas_Grid(gridname) fspace_1 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("equal_regions")) fspace_2 = atlas_functionspace_StructuredColumns(grid, atlas_Partitioner("regular_bands")) -call do_redistribute(fspace_1, fspace_2) +field = do_redistribute(fspace_1, fspace_2) +call field%data(field_v) +FCTEST_CHECK(maxval(field_v) == 1.) meshgenerator = atlas_MeshGenerator() mesh = meshgenerator%generate(grid, atlas_Partitioner("equal_regions")) fspace_1 = atlas_functionspace_NodeColumns(mesh) mesh = meshgenerator%generate(grid, atlas_Partitioner("regular_bands")) fspace_2 = atlas_functionspace_NodeColumns(mesh) -call do_redistribute(fspace_1, fspace_2) +field = do_redistribute(fspace_1, fspace_2) +call field%data(field_v) +FCTEST_CHECK(maxval(field_v) == 1.) fspace_2 = atlas_functionspace_EdgeColumns(mesh) mesh = meshgenerator%generate(grid, atlas_Partitioner("equal_regions")) fspace_1 = atlas_functionspace_EdgeColumns(mesh) -call do_redistribute(fspace_1, fspace_2) +field = do_redistribute(fspace_1, fspace_2) +call field%data(field_v) +FCTEST_CHECK(maxval(field_v) == 1.) call fspace_2%final() call fspace_1%final() @@ -123,4 +130,3 @@ end subroutine do_redistribute ! ----------------------------------------------------------------------------- END_TESTSUITE - From 35e190646195233488b3148abe5837959e3a01d7 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2023 15:43:40 +0100 Subject: [PATCH 15/16] Revert changes in existing C++ classes --- .../detail/RedistributeGeneric.cc | 22 +++++++++---------- .../detail/RedistributeGeneric.h | 1 - .../detail/RedistributeStructuredColumns.cc | 6 ++--- .../detail/RedistributeStructuredColumns.h | 4 ++-- .../detail/RedistributionImpl.h | 4 ---- 5 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/atlas/redistribution/detail/RedistributeGeneric.cc b/src/atlas/redistribution/detail/RedistributeGeneric.cc index d59748eb5..9e86fff15 100644 --- a/src/atlas/redistribution/detail/RedistributeGeneric.cc +++ b/src/atlas/redistribution/detail/RedistributeGeneric.cc @@ -304,20 +304,18 @@ void RedistributeGeneric::execute(const Field& sourceField, Field& targetField) void RedistributeGeneric::execute(const FieldSet& sourceFieldSet, FieldSet& targetFieldSet) const { // Check field set sizes match. - ATLAS_ASSERT(sourceFieldSet->size() == targetFieldSet->size()); + ATLAS_ASSERT(sourceFieldSet.size() == targetFieldSet.size()); // Redistribute fields. - auto targetFieldSetIt = targetFieldSet->begin(); - std::for_each(sourceFieldSet->cbegin(), sourceFieldSet->cend(), [&](const Field& sourceField) { - execute(sourceField, *targetFieldSetIt++); - return; - }); + for (idx_t i = 0; i < sourceFieldSet.size(); ++i) { + execute(sourceFieldSet[i], targetFieldSet[i]); + } } // Determine datatype. void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { // Available datatypes defined in array/LocalView.cc - switch (sourceField->datatype().kind()) { + switch (sourceField.datatype().kind()) { case array::DataType::KIND_REAL64: { return do_execute(sourceField, targetField); } @@ -331,7 +329,7 @@ void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetFiel return do_execute(sourceField, targetField); } default: { - ATLAS_THROW_EXCEPTION("No implementation for data type " + sourceField->datatype().str()); + ATLAS_THROW_EXCEPTION("No implementation for data type " + sourceField.datatype().str()); } } } @@ -340,7 +338,7 @@ void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetFiel template void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { // Available ranks defined in array/LocalView.cc - switch (sourceField->rank()) { + switch (sourceField.rank()) { case 1: { return do_execute(sourceField, targetField); } @@ -369,7 +367,7 @@ void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetFiel return do_execute(sourceField, targetField); } default: { - ATLAS_THROW_EXCEPTION("No implementation for rank " + std::to_string(sourceField->rank())); + ATLAS_THROW_EXCEPTION("No implementation for rank " + std::to_string(sourceField.rank())); } } } @@ -378,8 +376,8 @@ void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetFiel template void RedistributeGeneric::do_execute(const Field& sourceField, Field& targetField) const { // Get array views. - auto sourceView = array::make_view(*sourceField); - auto targetView = array::make_view(*targetField); + auto sourceView = array::make_view(sourceField); + auto targetView = array::make_view(targetField); const auto& comm = mpi::comm(mpi_comm_); auto mpi_size = comm.size(); diff --git a/src/atlas/redistribution/detail/RedistributeGeneric.h b/src/atlas/redistribution/detail/RedistributeGeneric.h index 1878aad67..a650fd02c 100644 --- a/src/atlas/redistribution/detail/RedistributeGeneric.h +++ b/src/atlas/redistribution/detail/RedistributeGeneric.h @@ -9,7 +9,6 @@ #include -#include "atlas/field/detail/FieldImpl.h" #include "atlas/redistribution/detail/RedistributionImpl.h" namespace atlas { diff --git a/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc b/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc index b8cfb10c6..3ef241fd7 100644 --- a/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc +++ b/src/atlas/redistribution/detail/RedistributeStructuredColumns.cc @@ -167,10 +167,10 @@ void RedistributeStructuredColumns::execute(const Field& sourceField, Field& tar void RedistributeStructuredColumns::execute(const FieldSet& sourceFieldSet, FieldSet& targetFieldSet) const { // Check that both FieldSets are the same size. - ATLAS_ASSERT(sourceFieldSet->size() == targetFieldSet->size()); + ATLAS_ASSERT(sourceFieldSet.size() == targetFieldSet.size()); - auto targetFieldSetIt = targetFieldSet->begin(); - std::for_each(sourceFieldSet->cbegin(), sourceFieldSet->cend(), [&](const Field& sourceField) { + auto targetFieldSetIt = targetFieldSet.begin(); + std::for_each(sourceFieldSet.cbegin(), sourceFieldSet.cend(), [&](const Field& sourceField) { execute(sourceField, *targetFieldSetIt++); return; }); diff --git a/src/atlas/redistribution/detail/RedistributeStructuredColumns.h b/src/atlas/redistribution/detail/RedistributeStructuredColumns.h index dec63b14d..7972078b8 100644 --- a/src/atlas/redistribution/detail/RedistributeStructuredColumns.h +++ b/src/atlas/redistribution/detail/RedistributeStructuredColumns.h @@ -15,8 +15,8 @@ namespace atlas { -class FieldImpl; -class FieldSetImpl; +class Field; +class FieldSet; class FunctionSpace; namespace functionspace { diff --git a/src/atlas/redistribution/detail/RedistributionImpl.h b/src/atlas/redistribution/detail/RedistributionImpl.h index f1f94c5aa..bcdefa3d8 100644 --- a/src/atlas/redistribution/detail/RedistributionImpl.h +++ b/src/atlas/redistribution/detail/RedistributionImpl.h @@ -11,13 +11,9 @@ #include "atlas/util/Object.h" namespace atlas { - namespace field { class Field; class FieldSet; - } - namespace functionspace { class FunctionSpace; - } } // namespace atlas namespace atlas { From adbb751ecf62068c26d6f43fd17e29ecc1e3084f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2023 15:51:20 +0100 Subject: [PATCH 16/16] Fix forward declare --- src/atlas/redistribution/detail/RedistributionInterface.cc | 3 ++- src/atlas/redistribution/detail/RedistributionInterface.h | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/atlas/redistribution/detail/RedistributionInterface.cc b/src/atlas/redistribution/detail/RedistributionInterface.cc index 0b66e2304..6f461967f 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.cc +++ b/src/atlas/redistribution/detail/RedistributionInterface.cc @@ -10,9 +10,10 @@ #include +#include "RedistributionInterface.h" + #include "RedistributeGeneric.h" #include "RedistributionImpl.h" -#include "RedistributionInterface.h" #include "atlas/functionspace/FunctionSpace.h" #include "atlas/redistribution/detail/RedistributionImplFactory.h" diff --git a/src/atlas/redistribution/detail/RedistributionInterface.h b/src/atlas/redistribution/detail/RedistributionInterface.h index 500e32c79..2d6cb3bd8 100644 --- a/src/atlas/redistribution/detail/RedistributionInterface.h +++ b/src/atlas/redistribution/detail/RedistributionInterface.h @@ -15,11 +15,10 @@ class Configuration; namespace atlas { namespace functionspace { -class FunctionSpace; +class FunctionSpaceImpl; } namespace field { -class Field; -class FieldSet; +class FieldImpl; } } // namespace atlas