WIP: rrange + corresp test
This commit is contained in:
parent
f7c7cd3363
commit
f55c38cc65
16 changed files with 241 additions and 59 deletions
|
@ -123,6 +123,14 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# CHECK LIBRARIES : mpi
|
||||||
|
|
||||||
|
if(DEFINED ENABLE_mpi)
|
||||||
|
set(ENABLE_mpi ${ENABLE_mpi} CACHE BOOL "enable mpi")
|
||||||
|
else()
|
||||||
|
set(ENABLE_mpi TRUE CACHE BOOL "enable mpi")
|
||||||
|
endif()
|
||||||
|
|
||||||
# DEFINES
|
# DEFINES
|
||||||
|
|
||||||
add_definitions(-DVERSION="${VERSION}")
|
add_definitions(-DVERSION="${VERSION}")
|
||||||
|
|
|
@ -12,4 +12,8 @@ if(ENABLE_cereal)
|
||||||
add_subdirectory(opt/cereal)
|
add_subdirectory(opt/cereal)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_mpi)
|
||||||
|
add_subdirectory(opt/mpi)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include/cnorxz)
|
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include/cnorxz)
|
||||||
|
|
|
@ -311,6 +311,7 @@ namespace CNORXZ
|
||||||
public:
|
public:
|
||||||
typedef RangeBase RB;
|
typedef RangeBase RB;
|
||||||
typedef YIndex IndexType;
|
typedef YIndex IndexType;
|
||||||
|
typedef typename IndexType::MetaType MetaType;
|
||||||
|
|
||||||
friend YRangeFactory;
|
friend YRangeFactory;
|
||||||
|
|
||||||
|
|
16
src/opt/mpi/CMakeLists.txt
Normal file
16
src/opt/mpi/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
find_package(MPI REQUIRED)
|
||||||
|
if(MPI_FOUND)
|
||||||
|
include_directories(${MPI_C_INCLUDE_DIRS})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "HDF5 not found")
|
||||||
|
endif()
|
||||||
|
message(STATUS "mpi lib = ${MPI_C_LIBRARIES}")
|
||||||
|
set(MPI_LIBS ${MPI_LIBRARIES})
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
add_subdirectory(lib)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
|
||||||
|
install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include/cnorxz/mpi)
|
14
src/opt/mpi/include/cnorxz_mpi.cc.h
Normal file
14
src/opt/mpi/include/cnorxz_mpi.cc.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/mpi/include/cnorxz_mpi.cc.h
|
||||||
|
@brief CNORXZ MPI template sources header
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "mpi_wrappers.cc.h"
|
||||||
|
//#include "rop_types.cc.h"
|
||||||
|
#include "rrange.cc.h"
|
20
src/opt/mpi/include/cnorxz_mpi.h
Normal file
20
src/opt/mpi/include/cnorxz_mpi.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/mpi/include/cnorxz_mpi.h
|
||||||
|
@brief CNORXZ MPI main header
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "mpi_base.h"
|
||||||
|
#include "mpi_wrappers.h"
|
||||||
|
//#include "raindex.h"
|
||||||
|
//#include "rarray.h"
|
||||||
|
//#include "rop_types.h"
|
||||||
|
#include "rrange.h"
|
||||||
|
#include "typemap.h"
|
||||||
|
|
||||||
|
#include "cnorxz_mpi.cc.h"
|
|
@ -20,6 +20,14 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
namespace mpi
|
namespace mpi
|
||||||
{
|
{
|
||||||
|
// class declarations
|
||||||
|
|
||||||
|
template <class RangeI, class RangeK>
|
||||||
|
class RRange;
|
||||||
|
|
||||||
|
template <class IndexI, class IndexK>
|
||||||
|
class RIndex;
|
||||||
|
|
||||||
// wrapper functions
|
// wrapper functions
|
||||||
|
|
||||||
/** Get number of THIS rank. */
|
/** Get number of THIS rank. */
|
||||||
|
|
|
@ -22,9 +22,9 @@ namespace CNORXZ
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void BCast<T>::bcast(T& d, SizeT root)
|
void BCast<T>::bcast(T& d, SizeT root)
|
||||||
{
|
{
|
||||||
static_assert( TypeMap<T>::exists, "no bcast implementation for given type" );
|
static_assert( Typemap<T>::exists, "no bcast implementation for given type" );
|
||||||
const int ret = MPI_Bcast( reinterpret_cast<void*>(&d), 1,
|
const int ret = MPI_Bcast( reinterpret_cast<void*>(&d), 1,
|
||||||
TypeMap<T>::value, MPI_COMM_WORLD );
|
Typemap<T>::value(), root, MPI_COMM_WORLD );
|
||||||
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
SizeT size = d.size();
|
SizeT size = d.size();
|
||||||
const int ret = MPI_Bcast( reinterpret_cast<void*>(&size), 1,
|
const int ret = MPI_Bcast( reinterpret_cast<void*>(&size), 1,
|
||||||
MPI_UNSIGNED_LONG, MPI_COMM_WORLD );
|
MPI_UNSIGNED_LONG, root, MPI_COMM_WORLD );
|
||||||
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
||||||
if(size != d.size()){
|
if(size != d.size()){
|
||||||
d.resize(size);
|
d.resize(size);
|
||||||
|
@ -47,7 +47,7 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const int ret2 = MPI_Bcast( reinterpret_cast<void*>(d.data()), size,
|
const int ret2 = MPI_Bcast( reinterpret_cast<void*>(d.data()), size,
|
||||||
TypeMap<T>::value, MPI_COMM_WORLD );
|
Typemap<T>::value(), root, MPI_COMM_WORLD );
|
||||||
CXZ_ASSERT(ret2 == MPI_SUCCESS, "got bcast error = " << ret2);
|
CXZ_ASSERT(ret2 == MPI_SUCCESS, "got bcast error = " << ret2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,15 +55,15 @@ namespace CNORXZ
|
||||||
template <typename T, SizeT N>
|
template <typename T, SizeT N>
|
||||||
void BCast<Arr<T,N>>::bcast(Arr<T,N>& d, SizeT root)
|
void BCast<Arr<T,N>>::bcast(Arr<T,N>& d, SizeT root)
|
||||||
{
|
{
|
||||||
if constexpr( BCast<T,N>::special ){
|
if constexpr( BCast<T>::special ){
|
||||||
for(auto& x: d){
|
for(auto& x: d){
|
||||||
bcast(x, root);
|
bcast(x, root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const int ret = MPI_Bcast( reinterpret_cast<void*>(d.data()), N,
|
const int ret = MPI_Bcast( reinterpret_cast<void*>(d.data()), N,
|
||||||
TypeMap<T>::value, MPI_COMM_WORLD );
|
Typemap<T>::value(), root, MPI_COMM_WORLD );
|
||||||
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret2);
|
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,25 +71,25 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
SizeT size = d.size();
|
SizeT size = d.size();
|
||||||
const int ret = MPI_Bcast( reinterpret_cast<void*>(&size), 1,
|
const int ret = MPI_Bcast( reinterpret_cast<void*>(&size), 1,
|
||||||
MPI_UNSIGNED_LONG, MPI_COMM_WORLD );
|
MPI_UNSIGNED_LONG, root, MPI_COMM_WORLD );
|
||||||
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
||||||
if(size != d.size()){
|
if(size != d.size()){
|
||||||
d.resize(size);
|
d.resize(size);
|
||||||
}
|
}
|
||||||
const int ret = MPI_Bcast( reinterpret_cast<void*>(d.data()), size,
|
const int ret2 = MPI_Bcast( reinterpret_cast<void*>(d.data()), size,
|
||||||
MPI_CHAR, MPI_COMM_WORLD );
|
MPI_CHAR, root, MPI_COMM_WORLD );
|
||||||
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
CXZ_ASSERT(ret2 == MPI_SUCCESS, "got bcast error = " << ret2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
void BCast<Tuple<Ts...>>::bcast(Tuple<Ts...>& d, SizeT root)
|
void BCast<Tuple<Ts...>>::bcast(Tuple<Ts...>& d, SizeT root)
|
||||||
{
|
{
|
||||||
if constexpr( ( BCast<Ts>::special or ... ) ){
|
if constexpr( ( BCast<Ts>::special or ... ) ){
|
||||||
ifor<0,sizeof...(Ts)>( [&](auto i) { bcast( std::get<i>(d), root ); }, NoF {} );
|
iter<0,sizeof...(Ts)>( [&](auto i) { bcast( std::get<i>(d), root ); }, NoF {} );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const int ret = MPI_Bcast( reinterpret_cast<void*>(&d), sizeof(d),
|
const int ret = MPI_Bcast( reinterpret_cast<void*>(&d), sizeof(d),
|
||||||
MPI_BYTE, MPI_COMM_WORLD );
|
MPI_BYTE, root, MPI_COMM_WORLD );
|
||||||
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
CXZ_ASSERT(ret == MPI_SUCCESS, "got bcast error = " << ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,8 @@ namespace CNORXZ
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void bcast(T& d, SizeT root)
|
void bcast(T& d, SizeT root)
|
||||||
{
|
{
|
||||||
return BCast<T>(d, root);
|
BCast<T>::bcast(d, root);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mpi
|
} // namespace mpi
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
#ifndef __cxz_mpi_wrappers_h__
|
#ifndef __cxz_mpi_wrappers_h__
|
||||||
#define __cxz_mpi_wrappers_h__
|
#define __cxz_mpi_wrappers_h__
|
||||||
|
|
||||||
#include "mpi.h"
|
#include "mpi_base.h"
|
||||||
#include "cnorxz.h"
|
|
||||||
#include "typemap.h"
|
#include "typemap.h"
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "rrange.h"
|
#include "rrange.h"
|
||||||
#include "mpi_wrappers.h"
|
#include "mpi_wrappers.h"
|
||||||
|
#include "mpi_wrappers.cc.h"
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
@ -27,24 +28,24 @@ namespace CNORXZ
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
RIndex<IndexI,IndexK>::RIndex(const RIndex& in) :
|
RIndex<IndexI,IndexK>::RIndex(const RIndex& in) :
|
||||||
mRange(in.mRange),
|
mRange(in.mRange),
|
||||||
mI(std::make_shared<Index>(mRange->local())),
|
mI(std::make_shared<IndexI>(mRange->local())),
|
||||||
mK(std::make_shared<YIndex>(mRange->geom()))
|
mK(std::make_shared<IndexK>(mRange->geom()))
|
||||||
{
|
{
|
||||||
*this = in.lex();
|
*this = in.lex();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
RIndex& RIndex<IndexI,IndexK>::operator=(const RIndex& in)
|
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator=(const RIndex& in)
|
||||||
{
|
{
|
||||||
mRange = in.mRange;
|
mRange = in.mRange;
|
||||||
mI = std::make_shared<Index>(mRange->local());
|
mI = std::make_shared<IndexI>(mRange->local());
|
||||||
mK = std::make_shared<YIndex>(mRange->geom());
|
mK = std::make_shared<IndexK>(mRange->geom());
|
||||||
*this = in.lex();
|
*this = in.lex();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
RIndex<IndexI,IndexK>::RIndex(const RangePtr& global, SizeT lexpos = 0) :
|
RIndex<IndexI,IndexK>::RIndex(const RangePtr& global, SizeT lexpos) :
|
||||||
mRange(rangeCast<RangeType>(global)),
|
mRange(rangeCast<RangeType>(global)),
|
||||||
mI(std::make_shared<IndexI>(mRange->local())),
|
mI(std::make_shared<IndexI>(mRange->local())),
|
||||||
mK(std::make_shared<IndexK>(mRange->geom()))
|
mK(std::make_shared<IndexK>(mRange->geom()))
|
||||||
|
@ -56,7 +57,7 @@ namespace CNORXZ
|
||||||
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator=(SizeT pos)
|
RIndex<IndexI,IndexK>& RIndex<IndexI,IndexK>::operator=(SizeT pos)
|
||||||
{
|
{
|
||||||
IB::mPos = pos; // = lex
|
IB::mPos = pos; // = lex
|
||||||
if(lexpos >= lmax().val()){
|
if(pos >= lmax().val()){
|
||||||
IB::mPos = pmax().val();
|
IB::mPos = pmax().val();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -155,15 +156,15 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
constexpr RIndex<IndexI,IndexK>::decltype(auto) pmax() const
|
constexpr decltype(auto) RIndex<IndexI,IndexK>::pmax() const
|
||||||
{
|
{
|
||||||
return mK->lmax().val() * mI->lmax().val();
|
return UPos(mK->lmax().val() * mI->lmax().val());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
constexpr RIndex<IndexI,IndexK>::decltype(auto) lmax() const
|
constexpr decltype(auto) RIndex<IndexI,IndexK>::lmax() const
|
||||||
{
|
{
|
||||||
return mK->lmax().val() * mI->lmax().val();
|
return UPos(mK->lmax().val() * mI->lmax().val());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
|
@ -173,7 +174,7 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
MetaType RIndex<IndexI,IndexK>::operator*() const
|
typename RIndex<IndexI,IndexK>::MetaType RIndex<IndexI,IndexK>::operator*() const
|
||||||
{
|
{
|
||||||
return meta();
|
return meta();
|
||||||
}
|
}
|
||||||
|
@ -185,7 +186,7 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
Sptr<RangeType> RIndex<IndexI,IndexK>::range() const
|
Sptr<typename RIndex<IndexI,IndexK>::RangeType> RIndex<IndexI,IndexK>::range() const
|
||||||
{
|
{
|
||||||
return mRange;
|
return mRange;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +195,7 @@ namespace CNORXZ
|
||||||
template <SizeT I>
|
template <SizeT I>
|
||||||
decltype(auto) RIndex<IndexI,IndexK>::stepSize(const IndexId<I>& id) const
|
decltype(auto) RIndex<IndexI,IndexK>::stepSize(const IndexId<I>& id) const
|
||||||
{
|
{
|
||||||
return mK->stepSize(id) * mI->lmax().val() + mI->stepSize(id);
|
return mK->stepSize(id) * mI->lmax() + mI->stepSize(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
|
@ -202,16 +203,20 @@ namespace CNORXZ
|
||||||
{
|
{
|
||||||
const SizeT r = mK->lex();
|
const SizeT r = mK->lex();
|
||||||
String o;
|
String o;
|
||||||
broadcast(r, mI->stringMeta(), &o);
|
auto x = mI->stringMeta();
|
||||||
|
bcast(x, r);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
MetaType RIndex<IndexI,IndexK>::meta() const
|
typename RIndex<IndexI,IndexK>::MetaType RIndex<IndexI,IndexK>::meta() const
|
||||||
{
|
{
|
||||||
const SizeT r = mK->lex();
|
|
||||||
MetaType o;
|
MetaType o;
|
||||||
broadcast(r, mI->meta(), &o);
|
if constexpr(Typemap<MetaType>::exists){
|
||||||
|
auto x = mI->meta();
|
||||||
|
const SizeT r = mK->lex();
|
||||||
|
bcast(x, r);
|
||||||
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +258,7 @@ namespace CNORXZ
|
||||||
constexpr decltype(auto) RIndex<IndexI,IndexK>::ifor(const Xpr& xpr, F&& f) const
|
constexpr decltype(auto) RIndex<IndexI,IndexK>::ifor(const Xpr& xpr, F&& f) const
|
||||||
{
|
{
|
||||||
CXZ_ERROR("not implemented");
|
CXZ_ERROR("not implemented");
|
||||||
return 0;
|
return xpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
|
@ -276,7 +281,7 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class IndexI, class IndexK>
|
template <class IndexI, class IndexK>
|
||||||
Sptr<Index> RIndex<IndexI,IndexK>::local() const
|
Sptr<IndexI> RIndex<IndexI,IndexK>::local() const
|
||||||
{
|
{
|
||||||
return mI;
|
return mI;
|
||||||
}
|
}
|
||||||
|
@ -299,8 +304,9 @@ namespace CNORXZ
|
||||||
<< ") does not match number of ranks ( = " << s << ")");
|
<< ") does not match number of ranks ( = " << s << ")");
|
||||||
if constexpr(has_static_sub<typename RangeI::IndexType>::value and
|
if constexpr(has_static_sub<typename RangeI::IndexType>::value and
|
||||||
has_static_sub<typename RangeK::IndexType>::value) {
|
has_static_sub<typename RangeK::IndexType>::value) {
|
||||||
static_assert(typename RangeI::NR == typename RangeK::NR,
|
constexpr SizeT NRI = RangeI::NR;
|
||||||
"ranges have to be of same dimension");
|
constexpr SizeT NRK = RangeK::NR;
|
||||||
|
static_assert(NRI == NRK, "ranges have to be of same dimension");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CXZ_ASSERT(ri->dim() == rk->dim(), "ranges have to be of same dimension, got "
|
CXZ_ASSERT(ri->dim() == rk->dim(), "ranges have to be of same dimension, got "
|
||||||
|
@ -311,7 +317,7 @@ namespace CNORXZ
|
||||||
template <class RangeI, class RangeK>
|
template <class RangeI, class RangeK>
|
||||||
void RRangeFactory<RangeI,RangeK>::make()
|
void RRangeFactory<RangeI,RangeK>::make()
|
||||||
{
|
{
|
||||||
Vector<Uuid> key = { mRI->key(), mRK->key() };
|
Vector<Uuid> key = { mRI->id(), mRK->id() };
|
||||||
const auto& info = typeid(RRange<RangeI,RangeK>);
|
const auto& info = typeid(RRange<RangeI,RangeK>);
|
||||||
mProd = this->fromCreated(info, key);
|
mProd = this->fromCreated(info, key);
|
||||||
if(mProd == nullptr) {
|
if(mProd == nullptr) {
|
||||||
|
@ -397,7 +403,7 @@ namespace CNORXZ
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class RangeI, class RangeK>
|
template <class RangeI, class RangeK>
|
||||||
const MetaType RRange<RangeI,RangeK>::get(SizeT pos) const
|
const typename RRange<RangeI,RangeK>::MetaType RRange<RangeI,RangeK>::get(SizeT pos) const
|
||||||
{
|
{
|
||||||
return (this->begin()+pos)->meta();
|
return (this->begin()+pos)->meta();
|
||||||
}
|
}
|
||||||
|
@ -425,6 +431,12 @@ namespace CNORXZ
|
||||||
mGeom(geom)
|
mGeom(geom)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
template <class RangeI, class RangeK>
|
||||||
|
Vector<Uuid> RRange<RangeI,RangeK>::key() const
|
||||||
|
{
|
||||||
|
return Vector<Uuid> { mLocal->id(), mGeom->id() };
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mpi
|
} // namespace mpi
|
||||||
} // namespace CNORXZ
|
} // namespace CNORXZ
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#ifndef __cxz_mpi_rrange_h__
|
#ifndef __cxz_mpi_rrange_h__
|
||||||
#define __cxz_mpi_rrange_h__
|
#define __cxz_mpi_rrange_h__
|
||||||
|
|
||||||
#include "cnorxz.h"
|
#include "mpi_base.h"
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
@ -140,7 +140,7 @@ namespace CNORXZ
|
||||||
SizeT rank() const;
|
SizeT rank() const;
|
||||||
|
|
||||||
/** Get the local index on THIS rank. */
|
/** Get the local index on THIS rank. */
|
||||||
Sptr<IndexI,IndexK> local() const;
|
Sptr<IndexI> local() const;
|
||||||
//!!!
|
//!!!
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -237,6 +237,7 @@ namespace CNORXZ
|
||||||
Sptr<RangeI> mLocal; /**< Local range of THIS rank. */
|
Sptr<RangeI> mLocal; /**< Local range of THIS rank. */
|
||||||
Sptr<RangeK> mGeom; /**< Rank geometry range. */
|
Sptr<RangeK> mGeom; /**< Rank geometry range. */
|
||||||
|
|
||||||
|
virtual Vector<Uuid> key() const override final;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Create RRange from global range and given rank geometry.
|
/** Create RRange from global range and given rank geometry.
|
||||||
|
|
|
@ -18,42 +18,42 @@ namespace CNORXZ
|
||||||
struct Typemap<int>
|
struct Typemap<int>
|
||||||
{
|
{
|
||||||
static constexpr bool exists = true;
|
static constexpr bool exists = true;
|
||||||
static constexpr MPI_Datatype value = MPI_INT;
|
static MPI_Datatype value() { return MPI_INT; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Typemap<unsigned>
|
struct Typemap<unsigned>
|
||||||
{
|
{
|
||||||
static constexpr bool exists = true;
|
static constexpr bool exists = true;
|
||||||
static constexpr MPI_Datatype value = MPI_UNSIGNED;
|
static MPI_Datatype value() { return MPI_UNSIGNED; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Typemap<long int>
|
struct Typemap<long int>
|
||||||
{
|
{
|
||||||
static constexpr bool exists = true;
|
static constexpr bool exists = true;
|
||||||
static constexpr MPI_Datatype value = MPI_LONG;
|
static MPI_Datatype value() { return MPI_LONG; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Typemap<unsigned long>
|
struct Typemap<unsigned long>
|
||||||
{
|
{
|
||||||
static constexpr bool exists = true;
|
static constexpr bool exists = true;
|
||||||
static constexpr MPI_Datatype value = MPI_UNSIGNED_LONG;
|
static MPI_Datatype value() { return MPI_UNSIGNED_LONG; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Typemap<double>
|
struct Typemap<double>
|
||||||
{
|
{
|
||||||
static constexpr bool exists = true;
|
static constexpr bool exists = true;
|
||||||
static constexpr MPI_Datatype value = MPI_DOUBLE;
|
static MPI_Datatype value() { return MPI_DOUBLE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Typemap<float>
|
struct Typemap<float>
|
||||||
{
|
{
|
||||||
static constexpr bool exists = true;
|
static constexpr bool exists = true;
|
||||||
static constexpr MPI_Datatype value = MPI_FLOAT;
|
static MPI_Datatype value() { return MPI_FLOAT; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// further !!!
|
// further !!!
|
||||||
|
|
18
src/opt/mpi/lib/CMakeLists.txt
Normal file
18
src/opt/mpi/lib/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
set(libcnorxzmpi_a_SOURCES
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/mpi_base.cc
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/rrange.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(cnorxzmpi_obj OBJECT
|
||||||
|
${libcnorxzmpi_a_SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(cnorxzmpi_obj PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||||
|
|
||||||
|
add_library(cnorxzmpi SHARED
|
||||||
|
$<TARGET_OBJECTS:cnorxzmpi_obj>
|
||||||
|
)
|
||||||
|
set_target_properties(cnorxzmpi PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||||
|
|
||||||
|
install(TARGETS cnorxzmpi LIBRARY DESTINATION ${INSTALL_PATH}/lib)
|
|
@ -10,6 +10,7 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "rrange.h"
|
#include "rrange.h"
|
||||||
|
#include "rrange.cc.h"
|
||||||
|
|
||||||
namespace CNORXZ
|
namespace CNORXZ
|
||||||
{
|
{
|
||||||
|
@ -27,14 +28,16 @@ namespace CNORXZ
|
||||||
"global range has to be of same dimension as geometry range, got "
|
"global range has to be of same dimension as geometry range, got "
|
||||||
<< global->dim() << " and " << geom->dim());
|
<< global->dim() << " and " << geom->dim());
|
||||||
MArray<RangePtr> o(geom);
|
MArray<RangePtr> o(geom);
|
||||||
YIndex k = geom->begin();
|
YIndex k(geom);
|
||||||
YIndex ke = geom->end();
|
YIndex ke(geom, geom->size());
|
||||||
auto mu = std::make_shared<CIndex>(geom->sub());
|
auto mu = std::make_shared<CIndex>(geom->sub().range());
|
||||||
MArray<MArray<RangePtr>> rs(geom->sub()->range());
|
MArray<MArray<RangePtr>> rs(geom->sub().range());
|
||||||
rs(mu) = operation( [&](const SizeT i) { return rsplit(globla->sub(i), geom->sub(i)); } , xpr(mu) );
|
rs(mu) = operation( [&](const SizeT i) { return rsplit(global->sub(i), geom->sub(i)); } , xpr(mu) );
|
||||||
Vector elem(geom->sub()->range());
|
Vector<RangePtr> elem(geom->dim());
|
||||||
for(; k != ke; ++k){
|
for(; k != ke; ++k){
|
||||||
mu->ifor( operation( [&](const SizeT i){ elem[i] = rs[i][k->pack()[i]]; }, xpr(mu) ) )();
|
mu->ifor( operation( [&](const SizeT i, const MArray<RangePtr>& el){
|
||||||
|
elem[i] = el[DIndex(k.pack()[i])];
|
||||||
|
}, xpr(mu), rs(mu) ), NoF {} )();
|
||||||
o[k] = YRangeFactory(elem).create();
|
o[k] = YRangeFactory(elem).create();
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
|
@ -42,13 +45,13 @@ namespace CNORXZ
|
||||||
else {
|
else {
|
||||||
CXZ_ASSERT(global->size() % geom->size() == 0,
|
CXZ_ASSERT(global->size() % geom->size() == 0,
|
||||||
"global range has to be dividible by geometry range, got "
|
"global range has to be dividible by geometry range, got "
|
||||||
<< global->size() << " and " << k->lmax().val());
|
<< global->size() << " and " << geom->size());
|
||||||
const SizeT n = global->size() / geom->size();
|
const SizeT n = global->size() / geom->size();
|
||||||
auto k = std::make_shared<CIndex>(geom);
|
auto k = std::make_shared<CIndex>(geom);
|
||||||
auto jb = global->begin();
|
auto jb = global->begin();
|
||||||
auto je = global->begin();
|
auto je = global->begin();
|
||||||
MArray<RangePtr> o(geom);
|
MArray<RangePtr> o(geom);
|
||||||
o(k) = operation( [&](const SizeT x){ jb = n*x; je = n*(x+1)-1; return jb.prange(je) } , xpr(k) );
|
o(k) = operation( [&](const SizeT x){ jb = n*x; je = n*(x+1)-1; return jb.prange(je); } , xpr(k) );
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,14 +61,15 @@ namespace CNORXZ
|
||||||
const MArray<RangePtr> rs = rsplit(global, geom);
|
const MArray<RangePtr> rs = rsplit(global, geom);
|
||||||
RangePtr o = nullptr;
|
RangePtr o = nullptr;
|
||||||
for(auto ri = rs.begin(); ri != rs.end(); ++ri){
|
for(auto ri = rs.begin(); ri != rs.end(); ++ri){
|
||||||
if(ri->lex() == getRangeNum()){
|
if(ri.lex() == getRankNumber()){
|
||||||
o = *ri;
|
o = *ri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(o);
|
assert(o);
|
||||||
auto loc = rangeCast<YRange>(global);
|
auto loc = rangeCast<YRange>(global);
|
||||||
auto geo = rangeCast<YRange>(geom);
|
auto geo = rangeCast<YRange>(geom);
|
||||||
return RRangeFactory<YRange,YRange>(loc, geom).create();
|
RRangeFactory<YRange,YRange> xx(loc, geo);
|
||||||
|
return RRangeFactory<YRange,YRange>(loc, geo).create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
7
src/opt/mpi/tests/CMakeLists.txt
Normal file
7
src/opt/mpi/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
add_definitions(-DTEST_NUMBER_FILE="${CMAKE_SOURCE_DIR}/src/tests/numbers.txt")
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/src/tests)
|
||||||
|
add_executable(mpirrutest rrange_unit_test.cc)
|
||||||
|
add_dependencies(mpirrutest cnorxz cnorxzmpi test_lib)
|
||||||
|
target_link_libraries(mpirrutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${MPI_LIBS} cnorxz cnorxzmpi test_lib)
|
||||||
|
add_test(NAME mpirrutest COMMAND mpirrutest)
|
69
src/opt/mpi/tests/rrange_unit_test.cc
Normal file
69
src/opt/mpi/tests/rrange_unit_test.cc
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
/**
|
||||||
|
|
||||||
|
@file opt/mpi/tests/rrange_unit_test.cc
|
||||||
|
@brief RRange unit tests.
|
||||||
|
|
||||||
|
Copyright (c) 2024 Christian Zimmermann. All rights reserved.
|
||||||
|
Mail: chizeta@f3l.de
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "cnorxz.h"
|
||||||
|
#include "cnorxz_mpi.h"
|
||||||
|
#include "test_numbers.h"
|
||||||
|
#include "rrange.cc.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace CNORXZ;
|
||||||
|
using Test::Numbers;
|
||||||
|
using namespace CNORXZ::mpi;
|
||||||
|
|
||||||
|
class RRange_Test : public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
RRange_Test()
|
||||||
|
{
|
||||||
|
CXZ_ASSERT(getNumRanks() == 4, "exptected 4 ranks");
|
||||||
|
Vector<Int> xs(12);
|
||||||
|
Vector<Int> ts(16);
|
||||||
|
mXRange = URangeFactory<Int>(xs).create();
|
||||||
|
mTRange = URangeFactory<Int>(ts).create();
|
||||||
|
Vector<RangePtr> rs { mTRange, mXRange, mXRange, mXRange };
|
||||||
|
mGRange = YRangeFactory(rs).create();
|
||||||
|
RangePtr g1 = CRangeFactory(1).create();
|
||||||
|
RangePtr g2 = CRangeFactory(2).create();
|
||||||
|
Vector<RangePtr> gs { g2, g1, g1, g2 };
|
||||||
|
mGeom = YRangeFactory(gs).create();
|
||||||
|
mRRange = rrange(mGRange, mGeom);
|
||||||
|
}
|
||||||
|
|
||||||
|
RangePtr mXRange;
|
||||||
|
RangePtr mTRange;
|
||||||
|
RangePtr mGRange;
|
||||||
|
RangePtr mGeom;
|
||||||
|
RangePtr mRRange;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(RRange_Test, Basics)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(mRRange->size(), mGRange->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
MPI_Init(&argc, &argv);
|
||||||
|
const int ret = RUN_ALL_TESTS();
|
||||||
|
MPI_Finalize();
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in a new issue