diff --git a/src/opt/mpi/include/mpi_base.h b/src/opt/mpi/include/mpi_base.h new file mode 100644 index 0000000..678eddb --- /dev/null +++ b/src/opt/mpi/include/mpi_base.h @@ -0,0 +1,34 @@ +// -*- C++ -*- + +/** + + @file + @brief + + Copyright (c) 2024 Christian Zimmermann. All rights reserved. + Mail: chizeta@f3l.de + +**/ + +#ifndef __cxz_mpi_base_h__ +#define __cxz_mpi_base_h__ + +#include "cnorxz.h" +#include "mpi.h" + +namespace CNORXZ +{ + namespace mpi + { + // wrapper functions + + /** Get number of THIS rank. */ + SizeT getRankNumber(); + + /** Get total number of ranks. */ + SizeT getNumRanks(); + + } // namespace mpi +} // namespace CNORXZ + +#endif diff --git a/src/opt/mpi/include/rrange.cc.h b/src/opt/mpi/include/rrange.cc.h index ed23b87..d928457 100644 --- a/src/opt/mpi/include/rrange.cc.h +++ b/src/opt/mpi/include/rrange.cc.h @@ -2,7 +2,7 @@ /** @file opt/mpi/include/rrange.cc.h - @brief RRange and RIndex declaration. + @brief RRange and RIndex template implementation. Copyright (c) 2024 Christian Zimmermann. All rights reserved. Mail: chizeta@f3l.de @@ -424,40 +424,6 @@ namespace CNORXZ mLocal(loc), mGeom(geom) {} - - /*===========================+ - | non-member functions | - +===========================*/ - - template - RangePtr rrange(const Sptr& global, const Sptr& geom) - { - if constexpr(has_static_sub::value and - has_static_sub::value) { - static_assert(typename RangeI::NR == typename RangeK::NR, - "ranges have to be of same dimension"); - - constexpr SizeT N = typename RangeI::NR; - auto mr = ifor<0,N>( [&](auto mu) { - return split( global->space()[CSizeT{}], geom->space()[CSizeT{}] ); - }, [](const auto&... r) { return xplMrange(r,...); } ); - typedef std::remove_reference::type RangeI; - return RRangeFactory(mr, geom).create(); // explicit range type!!! - } - // other cases!!! - else { - CXZ_ASSERT(global->dim() == geom->dim(), - "ranges have to be of same dimension, got " - << global->dim() << " and " << geom->dim()); - Vector o(global->dim()); - for(SizeT mu = 0; mu != global->dim(); ++mu){ - o[mu] = split( global->space()[mu], geom->space()[mu] ); - } - const Sptr yr = xplYrange(o); - return RRangeFactory(yr, geom).create(); - } - } - } // namespace mpi } // namespace CNORXZ diff --git a/src/opt/mpi/include/rrange.h b/src/opt/mpi/include/rrange.h index cab6b30..80a9a53 100644 --- a/src/opt/mpi/include/rrange.h +++ b/src/opt/mpi/include/rrange.h @@ -243,8 +243,7 @@ namespace CNORXZ @param global Global range. @param geom Rank geometry. */ - template - RangePtr rrange(const Sptr& global, const Sptr& geom); + RangePtr rrange(const RangePtr& global, const RangePtr& geom); } // namespace mpi } // namespace CNORXZ diff --git a/src/opt/mpi/lib/mpi_base.cc b/src/opt/mpi/lib/mpi_base.cc new file mode 100644 index 0000000..fda42c0 --- /dev/null +++ b/src/opt/mpi/lib/mpi_base.cc @@ -0,0 +1,38 @@ +// -*- C++ -*- + +/** + + @file + @brief + + Copyright (c) 2024 Christian Zimmermann. All rights reserved. + Mail: chizeta@f3l.de + +**/ + +#include "mpi_base.h" + +namespace CNORXZ +{ + namespace mpi + { + + SizeT getRankNumber() + { + int s; + const int ret = MPI_Comm_rank(MPI_COMM_WORLD, &s); + CXZ_ASSERT(ret == MPI_SUCCESS, "got mpi error = " << ret); + return static_cast(s); + } + + SizeT getNumRanks() + { + int s; + const int ret = MPI_Comm_size(MPI_COMM_WORLD, &s); + CXZ_ASSERT(ret == MPI_SUCCESS, "got mpi error = " << ret); + return static_cast(s); + } + + } // namespace mpi +} // namespace CNORXZ + diff --git a/src/opt/mpi/lib/rrange.cc b/src/opt/mpi/lib/rrange.cc new file mode 100644 index 0000000..ff93029 --- /dev/null +++ b/src/opt/mpi/lib/rrange.cc @@ -0,0 +1,74 @@ +// -*- C++ -*- +/** + + @file opt/mpi/lib/rrange.h + @brief RRange and RIndex implementation. + + Copyright (c) 2024 Christian Zimmermann. All rights reserved. + Mail: chizeta@f3l.de + +**/ + +#include "rrange.h" + +namespace CNORXZ +{ + namespace mpi + { + + /*===========================+ + | non-member functions | + +===========================*/ + + MArray rsplit(const RangePtr& global, const RangePtr& geom) + { + if(geom->dim() > 1){ + CXZ_ASSERT(global->dim() == geom->dim(), + "global range has to be of same dimension as geometry range, got " + << global->dim() << " and " << geom->dim()); + MArray o(geom); + YIndex k = geom->begin(); + YIndex ke = geom->end(); + auto mu = std::make_shared(geom->sub()); + MArray> rs(geom->sub()->range()); + rs(mu) = operation( [&](const SizeT i) { return rsplit(globla->sub(i), geom->sub(i)); } , xpr(mu) ); + Vector elem(geom->sub()->range()); + for(; k != ke; ++k){ + mu->ifor( operation( [&](const SizeT i){ elem[i] = rs[i][k->pack()[i]]; }, xpr(mu) ) )(); + o[k] = YRangeFactory(elem).create(); + } + return o; + } + else { + CXZ_ASSERT(global->size() % geom->size() == 0, + "global range has to be dividible by geometry range, got " + << global->size() << " and " << k->lmax().val()); + const SizeT n = global->size() / geom->size(); + auto k = std::make_shared(geom); + auto jb = global->begin(); + auto je = global->begin(); + MArray o(geom); + o(k) = operation( [&](const SizeT x){ jb = n*x; je = n*(x+1)-1; return jb.prange(je) } , xpr(k) ); + return o; + } + } + + RangePtr rrange(const RangePtr& global, const RangePtr& geom) + { + const MArray rs = rsplit(global, geom); + RangePtr o = nullptr; + for(auto ri = rs.begin(); ri != rs.end(); ++ri){ + if(ri->lex() == getRangeNum()){ + o = *ri; + } + } + assert(o); + auto loc = rangeCast(global); + auto geo = rangeCast(geom); + return RRangeFactory(loc, geom).create(); + } + + + } // namespace mpi +} // namespace CNORXZ +