Skip to content

Commit

Permalink
Add Fortran interface for Redistribution (#160)
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrdar authored Nov 9, 2023
1 parent f0d9114 commit 72e1846
Show file tree
Hide file tree
Showing 7 changed files with 403 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/atlas/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 66 additions & 0 deletions src/atlas/redistribution/detail/RedistributionInterface.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* (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 <cstring>

#include "RedistributionInterface.h"

#include "RedistributeGeneric.h"
#include "RedistributionImpl.h"

#include "atlas/functionspace/FunctionSpace.h"
#include "atlas/redistribution/detail/RedistributionImplFactory.h"

namespace atlas {
namespace redistribution {

// ----------------------------------------------------------------------------
// Fortran interfaces
// ----------------------------------------------------------------------------

extern "C" {

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 = detail::RedistributeGeneric::static_type();
config->get("type", type);
auto redist = redistribution::detail::RedistributionImplFactory::build(type);
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) {
Field f1(field_1);
Field f2(field_2);
This->execute(f1, f2);
}

const functionspace::FunctionSpaceImpl* atlas__Redistribution__source(
const detail::RedistributionImpl* This) {
return This->source().get();
}

const functionspace::FunctionSpaceImpl* atlas__Redistribution__target(
const detail::RedistributionImpl* This) {
return This->target().get();
}

}


// ----------------------------------------------------------------------------

} // namespace redistribution
} // namespace atlas
52 changes: 52 additions & 0 deletions src/atlas/redistribution/detail/RedistributionInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* (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

namespace eckit {
class Configuration;
}

namespace atlas {
namespace functionspace {
class FunctionSpaceImpl;
}
namespace field {
class FieldImpl;
}
} // namespace atlas

namespace atlas {
namespace redistribution {
namespace detail {
class RedistributionImpl;

// -------------------------------------------------------------------
// C wrapper interfaces to C++ routines
extern "C" {

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::FieldImpl* field_1, field::FieldImpl* field_2);

const functionspace::FunctionSpaceImpl* atlas__Redistribution__source(
const RedistributionImpl* This);

const functionspace::FunctionSpaceImpl* atlas__Redistribution__target(
const RedistributionImpl* This);

}


} // namespace detail
} // namespace redistribution
} // namespace atlas
4 changes: 4 additions & 0 deletions src/atlas_f/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
136 changes: 136 additions & 0 deletions src/atlas_f/redistribution/atlas_Redistribution_module.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
! (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_config_module, only : atlas_Config
use atlas_functionspace_module, only : atlas_FunctionSpace
use fckit_owned_object_module, only: fckit_owned_object

implicit none

public :: atlas_Redistribution

private

!------------------------------------------------------------------------------
TYPE, extends(fckit_owned_object) :: atlas_Redistribution

! Purpose :
! -------
! *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
#endif
END TYPE atlas_Redistribution

!------------------------------------------------------------------------------

interface atlas_Redistribution
module procedure ctor_cptr
module procedure ctor_create
end interface

private :: c_ptr
private :: fckit_owned_object

!========================================================
contains
!========================================================
! -----------------------------------------------------------------------------
! Redistribution routines

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
call this%reset_c_ptr( cptr )
call this%return()
end function

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
type(atlas_Redistribution) :: this
type(atlas_Config) :: config
config = empty_config()
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

subroutine atlas_Redistribution__execute(this, field_1, field_2)
use atlas_redistribution_c_binding
use atlas_Field_module
class(atlas_Redistribution), intent(in) :: this
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

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
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
11 changes: 11 additions & 0 deletions src/tests/redistribution/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@

if( atlas_HAVE_ATLAS_FUNCTIONSPACE )

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
MPI 8
Expand Down
Loading

0 comments on commit 72e1846

Please sign in to comment.