This commit is contained in:
Christian Zimmermann 2024-03-14 14:41:48 +01:00
parent af47dd01f9
commit f7c7cd3363
5 changed files with 148 additions and 37 deletions

View file

@ -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

View file

@ -2,7 +2,7 @@
/** /**
@file opt/mpi/include/rrange.cc.h @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. Copyright (c) 2024 Christian Zimmermann. All rights reserved.
Mail: chizeta@f3l.de Mail: chizeta@f3l.de
@ -424,40 +424,6 @@ namespace CNORXZ
mLocal(loc), mLocal(loc),
mGeom(geom) mGeom(geom)
{} {}
/*===========================+
| non-member functions |
+===========================*/
template <class RangeJ, class RangeK>
RangePtr rrange(const Sptr<RangeJ>& global, const Sptr<RangeK>& geom)
{
if constexpr(has_static_sub<typename RangeJ::IndexType>::value and
has_static_sub<typename RangeK::IndexType>::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<mu>{}], geom->space()[CSizeT<mu>{}] );
}, [](const auto&... r) { return xplMrange(r,...); } );
typedef std::remove_reference<decltype(*mr)>::type RangeI;
return RRangeFactory<RangeI,RangeK>(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<RangePtr> o(global->dim());
for(SizeT mu = 0; mu != global->dim(); ++mu){
o[mu] = split( global->space()[mu], geom->space()[mu] );
}
const Sptr<YRange> yr = xplYrange(o);
return RRangeFactory<YRange,RangeK>(yr, geom).create();
}
}
} // namespace mpi } // namespace mpi
} // namespace CNORXZ } // namespace CNORXZ

View file

@ -243,8 +243,7 @@ namespace CNORXZ
@param global Global range. @param global Global range.
@param geom Rank geometry. @param geom Rank geometry.
*/ */
template <class RangeJ, class RangeK> RangePtr rrange(const RangePtr& global, const RangePtr& geom);
RangePtr rrange(const Sptr<RangeJ>& global, const Sptr<RangeK>& geom);
} // namespace mpi } // namespace mpi
} // namespace CNORXZ } // namespace CNORXZ

View file

@ -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<SizeT>(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<SizeT>(s);
}
} // namespace mpi
} // namespace CNORXZ

74
src/opt/mpi/lib/rrange.cc Normal file
View file

@ -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<RangePtr> 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<RangePtr> o(geom);
YIndex k = geom->begin();
YIndex ke = geom->end();
auto mu = std::make_shared<CIndex>(geom->sub());
MArray<MArray<RangePtr>> 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<CIndex>(geom);
auto jb = global->begin();
auto je = global->begin();
MArray<RangePtr> 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<RangePtr> 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<YRange>(global);
auto geo = rangeCast<YRange>(geom);
return RRangeFactory<YRange,YRange>(loc, geom).create();
}
} // namespace mpi
} // namespace CNORXZ