fix in obj_handle + mpi: RArray test works

This commit is contained in:
Christian Zimmermann 2024-03-21 01:18:21 +01:00
parent c43698dc10
commit c1acda90f0
10 changed files with 105 additions and 50 deletions

View file

@ -41,7 +41,7 @@ namespace CNORXZ
template <typename T> template <typename T>
ObjHandle<T>& ObjHandle<T>::operator=(ObjHandle&& a) ObjHandle<T>& ObjHandle<T>::operator=(ObjHandle&& a)
{ {
mC = a.mC; mC = std::move(a.mC);
return *this; return *this;
} }

View file

@ -12,3 +12,5 @@
#include "mpi_wrappers.cc.h" #include "mpi_wrappers.cc.h"
//#include "rop_types.cc.h" //#include "rop_types.cc.h"
#include "rrange.cc.h" #include "rrange.cc.h"
#include "raindex.cc.h"
#include "rarray.cc.h"

View file

@ -11,10 +11,10 @@
#include "mpi_base.h" #include "mpi_base.h"
#include "mpi_wrappers.h" #include "mpi_wrappers.h"
//#include "raindex.h"
//#include "rarray.h"
//#include "rop_types.h"
#include "rrange.h" #include "rrange.h"
#include "raindex.h"
#include "rarray.h"
//#include "rop_types.h"
#include "typemap.h" #include "typemap.h"
#include "cnorxz_mpi.cc.h" #include "cnorxz_mpi.cc.h"

View file

@ -28,6 +28,12 @@ namespace CNORXZ
template <class IndexI, class IndexK> template <class IndexI, class IndexK>
class RIndex; class RIndex;
template <typename T>
class RAIndex;
template <typename T>
class RArray;
// wrapper functions // wrapper functions
/** Get number of THIS rank. */ /** Get number of THIS rank. */

View file

@ -12,7 +12,10 @@
#ifndef __cxz_mpi_raindex_cc_h__ #ifndef __cxz_mpi_raindex_cc_h__
#define __cxz_mpi_raindex_cc_h__ #define __cxz_mpi_raindex_cc_h__
namespace CNOXRZ #include <cstring>
#include "raindex.h"
namespace CNORXZ
{ {
namespace mpi namespace mpi
{ {
@ -20,7 +23,7 @@ namespace CNOXRZ
RAIndex<T>::RAIndex(const T* loc, const RangePtr& range, SizeT lexpos) : RAIndex<T>::RAIndex(const T* loc, const RangePtr& range, SizeT lexpos) :
RIndex<YIndex,YIndex>(range, lexpos), RIndex<YIndex,YIndex>(range, lexpos),
mLoc(loc), mLoc(loc),
mCur(i.rank()), mCur(rank()),
mThisRank(getRankNumber()) mThisRank(getRankNumber())
{ {
setBufferSize(); setBufferSize();
@ -30,9 +33,9 @@ namespace CNOXRZ
template <typename T> template <typename T>
RAIndex<T>::RAIndex(const T* loc, const RIndex<YIndex,YIndex>& i) : RAIndex<T>::RAIndex(const T* loc, const RIndex<YIndex,YIndex>& i) :
RIndex<YIndex,YIndex>(i) RIndex<YIndex,YIndex>(i),
mLoc(loc), mLoc(loc),
mCur(i.rank()), mCur(rank()),
mThisRank(getRankNumber()) mThisRank(getRankNumber())
{ {
setBufferSize(); setBufferSize();
@ -65,25 +68,25 @@ namespace CNOXRZ
template <typename T> template <typename T>
const T& RAIndex<T>::operator*() const const T& RAIndex<T>::operator*() const
{ {
if(rank() != mThisRank){
if(mCur != rank()){ if(mCur != rank()){
setBuffer(); setBuffer();
} }
if(rank() != mThisRank){
return mBuf[local()->pos() % mBufSize]; return mBuf[local()->pos() % mBufSize];
} }
else { else {
mLoc[local()->pos()]; return mLoc[local()->pos()];
} }
} }
template <typename T> template <typename T>
const T* RAIndex<T>::operator->() const const T* RAIndex<T>::operator->() const
{ {
if(rank() != mThisRank){
if(mCur != rank()){ if(mCur != rank()){
setBuffer(); setBuffer();
} }
return mBuf + local()->pos() % mBufSize; if(rank() != mThisRank){
return mBuf.data() + local()->pos() % mBufSize;
} }
else { else {
return mLoc + local()->pos(); return mLoc + local()->pos();
@ -104,16 +107,20 @@ namespace CNOXRZ
} }
template <typename T> template <typename T>
void RAIndex<T>::setBuffer() void RAIndex<T>::setBuffer() const
{ {
if(mBuf.size() != mBufSize){ if(mBuf.size() != mBufSize){
mBuf.resize(mBufSize); mBuf.resize(mBufSize);
} }
// A Bcast alternative with const pointer to source would be better... // A Bcast alternative with const pointer to source would be better...
std::memcpy(mBuf.data(), mLoc + local()->pos() / mBufSize, mBufSize*sizeof(T)); const T* d = mLoc + (local()->pos() / mBufSize) * mBufSize;
std::memcpy(mBuf.data(), d, mBufSize*sizeof(T));
MPI_Bcast(mBuf.data(), mBufSize*sizeof(T), MPI_BYTE, static_cast<int>(rank()), MPI_Bcast(mBuf.data(), mBufSize*sizeof(T), MPI_BYTE, static_cast<int>(rank()),
MPI_COMM_WORLD ); MPI_COMM_WORLD );
mCur = rank();
} }
} // namespace mpi } // namespace mpi
} // namespace CNOXRZ } // namespace CNOXRZ
#endif

View file

@ -13,6 +13,7 @@
#define __cxz_mpi_raindex_h__ #define __cxz_mpi_raindex_h__
#include "cnorxz.h" #include "cnorxz.h"
#include "rrange.h"
namespace CNORXZ namespace CNORXZ
{ {
@ -49,11 +50,11 @@ namespace CNORXZ
private: private:
void setBuffer(); void setBuffer() const;
const T* mLoc = nullptr; const T* mLoc = nullptr;
Vector<T> mBuf; // used if iterating over content on different rank mutable Vector<T> mBuf; // used if iterating over content on different rank
SizeT mCur; // current rank in the buffer mutable SizeT mCur; // current rank in the buffer
SizeT mBufSize; SizeT mBufSize;
SizeT mThisRank; SizeT mThisRank;
}; };

View file

@ -12,16 +12,34 @@
#ifndef __cxz_mpi_rarray_cc_h__ #ifndef __cxz_mpi_rarray_cc_h__
#define __cxz_mpi_rarray_cc_h__ #define __cxz_mpi_rarray_cc_h__
#include "rarray.h"
#include "raindex.h"
namespace CNORXZ namespace CNORXZ
{ {
namespace mpi namespace mpi
{ {
template <typename T> template <typename T>
RCArray<T>::RCArray(const Sptr<CArrayBase<T>> a, const RangePtr& geom) : RCArray<T>::RCArray(const RCArray& a) :
mA(a), mA(a.mA->copy()),
mGeom(a.mGeom),
mGlobal(a.mGlobal)
{}
template <typename T>
RCArray<T>& RCArray<T>::operator=(const RCArray& a)
{
mA = ObjHandle<CArrayBase<T>>(a.mA->copy());
mGeom = a.mGeom;
mGlobal = a.mGlobal;
}
template <typename T>
RCArray<T>::RCArray(const CArrayBase<T>& a, const RangePtr& geom) :
mA(a.copy()),
mGeom(geom), mGeom(geom),
mGlobal(RRangeFactory(a->range(),mGeom).create()) mGlobal(RRangeFactory(rangeCast<YRange>(a.range()),rangeCast<YRange>(mGeom)).create())
{} {}
template <typename T> template <typename T>
@ -102,14 +120,16 @@ namespace CNORXZ
inline decltype(auto) RCArray<T>::operator()(const SPack<Indices...>& pack) const inline decltype(auto) RCArray<T>::operator()(const SPack<Indices...>& pack) const
{ {
CXZ_ERROR("not implemented"); CXZ_ERROR("not implemented");
return COpRoot<T,Index>(); //return COpRoot<T,Index>();
return 0;
} }
template <typename T> template <typename T>
inline decltype(auto) RCArray<T>::operator()(const DPack& pack) const inline decltype(auto) RCArray<T>::operator()(const DPack& pack) const
{ {
CXZ_ERROR("not implemented"); CXZ_ERROR("not implemented");
return COpRoot<T,Index>(); //return COpRoot<T,Index>();
return 0;
} }
template <typename T> template <typename T>
@ -131,27 +151,27 @@ namespace CNORXZ
} }
template <typename T> template <typename T>
const_iterator RCArray<T>::begin() const typename RCArray<T>::const_iterator RCArray<T>::begin() const
{ {
return const_iterator(mA.data(), mGlobal); return const_iterator(mA->data(), mGlobal);
} }
template <typename T> template <typename T>
const_iterator RCArray<T>::end() const typename RCArray<T>::const_iterator RCArray<T>::end() const
{ {
return const_iterator(mA.data(), mGlobal, mGlobal->size()); return const_iterator(mA->data(), mGlobal, mGlobal->size());
} }
template <typename T> template <typename T>
const_iterator RCArray<T>::cbegin() const typename RCArray<T>::const_iterator RCArray<T>::cbegin() const
{ {
return const_iterator(mA.data(), mGlobal); return const_iterator(mA->data(), mGlobal);
} }
template <typename T> template <typename T>
const_iterator RCArray<T>::cend() const typename RCArray<T>::const_iterator RCArray<T>::cend() const
{ {
return const_iterator(mA.data(), mGlobal, mGlobal->size()); return const_iterator(mA->data(), mGlobal, mGlobal->size());
} }
template <typename T> template <typename T>

View file

@ -13,6 +13,7 @@
#define __cxz_mpi_rarray_h__ #define __cxz_mpi_rarray_h__
#include "cnorxz.h" #include "cnorxz.h"
#include "raindex.h"
namespace CNORXZ namespace CNORXZ
{ {
@ -26,15 +27,18 @@ namespace CNORXZ
class RCArray class RCArray
{ {
public: public:
typedef RAIndex const_iterator; typedef RAIndex<T> const_iterator;
DEFAULT_MEMBERS(RCArray); DEFAULT_C(RCArray);
DEFAULT_MOVE(RCArray);
RCArray(const RCArray& a);
RCArray& operator=(const RCArray& a);
/** Construct from local array object. /** Construct from local array object.
@param a Local array. @param a Local array.
@param geom Rank geometry. @param geom Rank geometry.
*/ */
RCArray(const Sptr<CArrayBase<T>> a, const RangePtr& geom); RCArray(const CArrayBase<T>& a, const RangePtr& geom);
/** @copydoc CArrayBase::operator[] */ /** @copydoc CArrayBase::operator[] */
template <typename I, typename M> template <typename I, typename M>

View file

@ -1,8 +1,15 @@
add_definitions(-DTEST_NUMBER_FILE="${CMAKE_SOURCE_DIR}/src/tests/numbers.txt") add_definitions(-DTEST_NUMBER_FILE="${CMAKE_SOURCE_DIR}/src/tests/numbers.txt")
include_directories(${CMAKE_SOURCE_DIR}/src/tests) include_directories(${CMAKE_SOURCE_DIR}/src/tests)
add_executable(mpirrutest rrange_unit_test.cc) add_executable(mpirrutest rrange_unit_test.cc)
add_dependencies(mpirrutest cnorxz cnorxzmpi test_lib) add_dependencies(mpirrutest cnorxz cnorxzmpi test_lib)
target_link_libraries(mpirrutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${MPI_LIBS} cnorxz cnorxzmpi test_lib) target_link_libraries(mpirrutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${MPI_LIBS} cnorxz cnorxzmpi test_lib)
set(MPI_TEST_COMMAND mpirun -n 4 mpirrutest) set(MPI_TEST_COMMAND mpirun -n 4 mpirrutest)
add_test(NAME mpirrutest COMMAND ${MPI_TEST_COMMAND}) add_test(NAME mpirrutest COMMAND ${MPI_TEST_COMMAND})
add_executable(mpirautest rarray_unit_test.cc)
add_dependencies(mpirautest cnorxz cnorxzmpi test_lib)
target_link_libraries(mpirautest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${MPI_LIBS} cnorxz cnorxzmpi test_lib)
set(MPI_TEST_COMMAND mpirun -n 4 mpirautest)
add_test(NAME mpirautest COMMAND ${MPI_TEST_COMMAND})

View file

@ -77,16 +77,23 @@ namespace
mGeom = YRangeFactory(gs).create(); mGeom = YRangeFactory(gs).create();
mRRange = rrange(mGRange, mGeom); mRRange = rrange(mGRange, mGeom);
const SizeT size = ts.size()*xs.size()*xs.size()*xs.size(); const SizeT size = ts.size()*xs.size()*xs.size()*xs.size();
Vector<Double> vec = Numbers::get(0,size/4+10); const SizeT locsize = size/4;
Vector<Double> data(size); Vector<Double> vec = Numbers::get(0,locsize+10);
Vector<Double> mData(size*4); Vector<Double> data(locsize);
mData.resize(size);
const SizeT myrank = getRankNumber(); const SizeT myrank = getRankNumber();
for(SizeT i = 0; i != size; ++i){ for(SizeT i = 0; i != locsize; ++i){
assert(i < data.size());
data[i] = vec[i] * vec[i+myrank] / vec[i+2*myrank]; data[i] = vec[i] * vec[i+myrank] / vec[i+2*myrank];
mData[i + size*myrank] = data[i]; assert(i + locsize*myrank < mData.size());
MPI_Bcast(mData.data() + size*i, size, MPI_DOUBLE, i, MPI_COMM_WORLD); mData[i + locsize*myrank] = data[i];
} }
mLoc = std::make_shared<MArray<Double>>( mRRange->sub(1), data); MPI_Barrier(MPI_COMM_WORLD);
for(SizeT r = 0; r != 4; ++r){
MPI_Bcast(mData.data() + locsize*r, locsize, MPI_DOUBLE, r, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
}
mLoc = MArray<Double>( mRRange->sub(1), data);
mA = RCArray<Double>(mLoc, mGeom); mA = RCArray<Double>(mLoc, mGeom);
} }
@ -95,22 +102,23 @@ namespace
RangePtr mGRange; RangePtr mGRange;
RangePtr mGeom; RangePtr mGeom;
RangePtr mRRange; RangePtr mRRange;
Sptr<MArray<Double>> mLoc; MArray<Double> mLoc;
RCArray mA; RCArray<Double> mA;
Vector<Double> mData; Vector<Double> mData;
}; };
TEST_F(RArray_Test, Basics) TEST_F(RCArray_Test, Basics)
{ {
EXPECT_EQ(mA.size(), mRRange->size()); EXPECT_EQ(mA.size(), mRRange->size());
} }
TEST_F(RArray_Test, GlobalIterate) TEST_F(RCArray_Test, GlobalIterate)
{ {
const SizeT size = mRRange->sub(1)->size(); const SizeT size = mRRange->sub(1)->size();
auto e = mA.end(); auto e = mA.end();
for(auto i = mA.begin(); i != e; ++i){ for(auto i = mA.begin(); i != e; ++i){
EXPECT_EQ(*i, mData[i.rank()*size + i.local().pos()]); const Double x = *i;
EXPECT_EQ(x, mData[i.rank()*size + i.local()->pos()]);
} }
} }
} }