Templatize SliceUnion
This commit is contained in:
parent
4543e712b3
commit
6776a7134c
108
atrip.org
108
atrip.org
@ -613,8 +613,8 @@ namespace atrip {
|
|||||||
|
|
||||||
namespace atrip {
|
namespace atrip {
|
||||||
|
|
||||||
|
template <typename F=double>
|
||||||
struct SliceUnion {
|
struct SliceUnion {
|
||||||
using F = double;
|
|
||||||
using Tensor = CTF::Tensor<F>;
|
using Tensor = CTF::Tensor<F>;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
@ -627,7 +627,7 @@ namespace atrip {
|
|||||||
* This means that there can be at most one slice with a given Ty_x_Tu.
|
* This means that there can be at most one slice with a given Ty_x_Tu.
|
||||||
*/
|
*/
|
||||||
void checkForDuplicates() const {
|
void checkForDuplicates() const {
|
||||||
std::vector<Slice::Ty_x_Tu> tytus;
|
std::vector<typename Slice<F>::Ty_x_Tu> tytus;
|
||||||
for (auto const& s: slices) {
|
for (auto const& s: slices) {
|
||||||
if (s.isFree()) continue;
|
if (s.isFree()) continue;
|
||||||
tytus.push_back({s.info.type, s.info.tuple});
|
tytus.push_back({s.info.type, s.info.tuple});
|
||||||
@ -640,13 +640,13 @@ namespace atrip {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Slice::Ty_x_Tu> neededSlices(ABCTuple const& abc) {
|
std::vector<typename Slice<F>::Ty_x_Tu> neededSlices(ABCTuple const& abc) {
|
||||||
std::vector<Slice::Ty_x_Tu> needed(sliceTypes.size());
|
std::vector<typename Slice<F>::Ty_x_Tu> needed(sliceTypes.size());
|
||||||
// build the needed vector
|
// build the needed vector
|
||||||
std::transform(sliceTypes.begin(), sliceTypes.end(),
|
std::transform(sliceTypes.begin(), sliceTypes.end(),
|
||||||
needed.begin(),
|
needed.begin(),
|
||||||
[&abc](Slice::Type const type) {
|
[&abc](typename Slice<F>::Type const type) {
|
||||||
auto tuple = Slice::subtupleBySlice(abc, type);
|
auto tuple = Slice<F>::subtupleBySlice(abc, type);
|
||||||
return std::make_pair(type, tuple);
|
return std::make_pair(type, tuple);
|
||||||
});
|
});
|
||||||
return needed;
|
return needed;
|
||||||
@ -671,8 +671,9 @@ namespace atrip {
|
|||||||
* slices.
|
* slices.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Slice::LocalDatabase buildLocalDatabase(ABCTuple const& abc) {
|
typename
|
||||||
Slice::LocalDatabase result;
|
Slice<F>::LocalDatabase buildLocalDatabase(ABCTuple const& abc) {
|
||||||
|
typename Slice<F>::LocalDatabase result;
|
||||||
|
|
||||||
auto const needed = neededSlices(abc);
|
auto const needed = neededSlices(abc);
|
||||||
|
|
||||||
@ -702,7 +703,7 @@ namespace atrip {
|
|||||||
// need
|
// need
|
||||||
auto const& it
|
auto const& it
|
||||||
= std::find_if(slices.begin(), slices.end(),
|
= std::find_if(slices.begin(), slices.end(),
|
||||||
[&tuple, &type](Slice const& other) {
|
[&tuple, &type](Slice<F> const& other) {
|
||||||
return other.info.tuple == tuple
|
return other.info.tuple == tuple
|
||||||
&& other.info.type == type
|
&& other.info.type == type
|
||||||
// we only want another slice when it
|
// we only want another slice when it
|
||||||
@ -728,7 +729,7 @@ namespace atrip {
|
|||||||
// tuple and that has a valid data pointer.
|
// tuple and that has a valid data pointer.
|
||||||
auto const& recycleIt
|
auto const& recycleIt
|
||||||
= std::find_if(slices.begin(), slices.end(),
|
= std::find_if(slices.begin(), slices.end(),
|
||||||
[&tuple, &type](Slice const& other) {
|
[&tuple, &type](Slice<F> const& other) {
|
||||||
return other.info.tuple == tuple
|
return other.info.tuple == tuple
|
||||||
&& other.info.type != type
|
&& other.info.type != type
|
||||||
&& other.isRecyclable()
|
&& other.isRecyclable()
|
||||||
@ -739,13 +740,13 @@ namespace atrip {
|
|||||||
// (which should exist by construction :THINK)
|
// (which should exist by construction :THINK)
|
||||||
//
|
//
|
||||||
if (recycleIt != slices.end()) {
|
if (recycleIt != slices.end()) {
|
||||||
auto& blank = Slice::findOneByType(slices, Slice::Blank);
|
auto& blank = Slice<F>::findOneByType(slices, Slice<F>::Blank);
|
||||||
// TODO: formalize this through a method to copy information
|
// TODO: formalize this through a method to copy information
|
||||||
// from another slice
|
// from another slice
|
||||||
blank.data = recycleIt->data;
|
blank.data = recycleIt->data;
|
||||||
blank.info.type = type;
|
blank.info.type = type;
|
||||||
blank.info.tuple = tuple;
|
blank.info.tuple = tuple;
|
||||||
blank.info.state = Slice::Recycled;
|
blank.info.state = Slice<F>::Recycled;
|
||||||
blank.info.from = from;
|
blank.info.from = from;
|
||||||
blank.info.recycling = recycleIt->info.type;
|
blank.info.recycling = recycleIt->info.type;
|
||||||
result.push_back({name, blank.info});
|
result.push_back({name, blank.info});
|
||||||
@ -772,17 +773,17 @@ namespace atrip {
|
|||||||
<< " for tuple " << tuple[0] << ", " << tuple[1]
|
<< " for tuple " << tuple[0] << ", " << tuple[1]
|
||||||
<< "\n"
|
<< "\n"
|
||||||
;
|
;
|
||||||
auto& blank = Slice::findOneByType(slices, Slice::Blank);
|
auto& blank = Slice<F>::findOneByType(slices, Slice<F>::Blank);
|
||||||
blank.info.type = type;
|
blank.info.type = type;
|
||||||
blank.info.tuple = tuple;
|
blank.info.tuple = tuple;
|
||||||
blank.info.from = from;
|
blank.info.from = from;
|
||||||
|
|
||||||
// Handle self sufficiency
|
// Handle self sufficiency
|
||||||
blank.info.state = Atrip::rank == from.rank
|
blank.info.state = Atrip::rank == from.rank
|
||||||
? Slice::SelfSufficient
|
? Slice<F>::SelfSufficient
|
||||||
: Slice::Fetch
|
: Slice<F>::Fetch
|
||||||
;
|
;
|
||||||
if (blank.info.state == Slice::SelfSufficient) {
|
if (blank.info.state == Slice<F>::SelfSufficient) {
|
||||||
blank.data = sources[from.source].data();
|
blank.data = sources[from.source].data();
|
||||||
} else {
|
} else {
|
||||||
if (freePointers.size() == 0)
|
if (freePointers.size() == 0)
|
||||||
@ -826,7 +827,7 @@ namespace atrip {
|
|||||||
// try to find the slice in the needed slices list
|
// try to find the slice in the needed slices list
|
||||||
auto const found
|
auto const found
|
||||||
= std::find_if(needed.begin(), needed.end(),
|
= std::find_if(needed.begin(), needed.end(),
|
||||||
[&slice] (Slice::Ty_x_Tu const& tytu) {
|
[&slice] (typename Slice<F>::Ty_x_Tu const& tytu) {
|
||||||
return slice.info.tuple == tytu.second
|
return slice.info.tuple == tytu.second
|
||||||
&& slice.info.type == tytu.first
|
&& slice.info.type == tytu.first
|
||||||
;
|
;
|
||||||
@ -845,7 +846,7 @@ namespace atrip {
|
|||||||
|
|
||||||
// allow to gc unwrapped and recycled, never Fetch,
|
// allow to gc unwrapped and recycled, never Fetch,
|
||||||
// if we have a Fetch slice then something has gone very wrong.
|
// if we have a Fetch slice then something has gone very wrong.
|
||||||
if (!slice.isUnwrapped() && slice.info.state != Slice::Recycled)
|
if (!slice.isUnwrapped() && slice.info.state != Slice<F>::Recycled)
|
||||||
throw
|
throw
|
||||||
std::domain_error("Trying to garbage collect "
|
std::domain_error("Trying to garbage collect "
|
||||||
" a non-unwrapped slice! "
|
" a non-unwrapped slice! "
|
||||||
@ -866,13 +867,13 @@ namespace atrip {
|
|||||||
// - we should make sure that the data pointer of slice
|
// - we should make sure that the data pointer of slice
|
||||||
// does not get freed.
|
// does not get freed.
|
||||||
//
|
//
|
||||||
if (slice.info.state == Slice::Ready) {
|
if (slice.info.state == Slice<F>::Ready) {
|
||||||
WITH_OCD WITH_RANK
|
WITH_OCD WITH_RANK
|
||||||
<< "__gc__:" << "checking for data recycled dependencies\n";
|
<< "__gc__:" << "checking for data recycled dependencies\n";
|
||||||
auto recycled
|
auto recycled
|
||||||
= Slice::hasRecycledReferencingToIt(slices, slice.info);
|
= Slice<F>::hasRecycledReferencingToIt(slices, slice.info);
|
||||||
if (recycled.size()) {
|
if (recycled.size()) {
|
||||||
Slice* newReady = recycled[0];
|
Slice<F>* newReady = recycled[0];
|
||||||
WITH_OCD WITH_RANK
|
WITH_OCD WITH_RANK
|
||||||
<< "__gc__:" << "swaping recycled "
|
<< "__gc__:" << "swaping recycled "
|
||||||
<< pretty_print(newReady->info)
|
<< pretty_print(newReady->info)
|
||||||
@ -897,8 +898,8 @@ namespace atrip {
|
|||||||
|
|
||||||
// if the slice is self sufficient, do not dare touching the
|
// if the slice is self sufficient, do not dare touching the
|
||||||
// pointer, since it is a pointer to our sources in our rank.
|
// pointer, since it is a pointer to our sources in our rank.
|
||||||
if ( slice.info.state == Slice::SelfSufficient
|
if ( slice.info.state == Slice<F>::SelfSufficient
|
||||||
|| slice.info.state == Slice::Recycled
|
|| slice.info.state == Slice<F>::Recycled
|
||||||
) {
|
) {
|
||||||
freeSlicePointer = false;
|
freeSlicePointer = false;
|
||||||
}
|
}
|
||||||
@ -920,7 +921,8 @@ namespace atrip {
|
|||||||
// at this point, let us blank the slice
|
// at this point, let us blank the slice
|
||||||
WITH_RANK << "~~~:cl(" << name << ")"
|
WITH_RANK << "~~~:cl(" << name << ")"
|
||||||
<< " freeing up slice "
|
<< " freeing up slice "
|
||||||
<< " info " << slice.info
|
// TODO: make this possible
|
||||||
|
// << " info " << slice.info
|
||||||
<< "\n";
|
<< "\n";
|
||||||
slice.free();
|
slice.free();
|
||||||
}
|
}
|
||||||
@ -930,13 +932,13 @@ namespace atrip {
|
|||||||
|
|
||||||
// CONSTRUCTOR
|
// CONSTRUCTOR
|
||||||
SliceUnion( Tensor const& sourceTensor
|
SliceUnion( Tensor const& sourceTensor
|
||||||
, std::vector<Slice::Type> sliceTypes_
|
, std::vector<typename Slice<F>::Type> sliceTypes_
|
||||||
, std::vector<size_t> sliceLength_
|
, std::vector<size_t> sliceLength_
|
||||||
, std::vector<size_t> paramLength
|
, std::vector<size_t> paramLength
|
||||||
, size_t np
|
, size_t np
|
||||||
, MPI_Comm child_world
|
, MPI_Comm child_world
|
||||||
, MPI_Comm global_world
|
, MPI_Comm global_world
|
||||||
, Slice::Name name_
|
, typename Slice<F>::Name name_
|
||||||
, size_t nSliceBuffers = 4
|
, size_t nSliceBuffers = 4
|
||||||
)
|
)
|
||||||
: rankMap(paramLength, np)
|
: rankMap(paramLength, np)
|
||||||
@ -951,13 +953,13 @@ namespace atrip {
|
|||||||
, name(name_)
|
, name(name_)
|
||||||
, sliceTypes(sliceTypes_)
|
, sliceTypes(sliceTypes_)
|
||||||
, sliceBuffers(nSliceBuffers, sources[0])
|
, sliceBuffers(nSliceBuffers, sources[0])
|
||||||
//, slices(2 * sliceTypes.size(), Slice{ sources[0].size() })
|
//, slices(2 * sliceTypes.size(), Slice<F>{ sources[0].size() })
|
||||||
{ // constructor begin
|
{ // constructor begin
|
||||||
|
|
||||||
LOG(0,"Atrip") << "INIT SliceUnion: " << name << "\n";
|
LOG(0,"Atrip") << "INIT SliceUnion: " << name << "\n";
|
||||||
|
|
||||||
slices
|
slices
|
||||||
= std::vector<Slice>(2 * sliceTypes.size(), { sources[0].size() });
|
= std::vector<Slice<F>>(2 * sliceTypes.size(), { sources[0].size() });
|
||||||
// TODO: think exactly ^------------------- about this number
|
// TODO: think exactly ^------------------- about this number
|
||||||
|
|
||||||
// initialize the freePointers with the pointers to the buffers
|
// initialize the freePointers with the pointers to the buffers
|
||||||
@ -1026,19 +1028,19 @@ namespace atrip {
|
|||||||
* \brief Send asynchronously only if the state is Fetch
|
* \brief Send asynchronously only if the state is Fetch
|
||||||
*/
|
*/
|
||||||
void send( size_t otherRank
|
void send( size_t otherRank
|
||||||
, Slice::Info const& info
|
, typename Slice<F>::Info const& info
|
||||||
, size_t tag) const noexcept {
|
, size_t tag) const noexcept {
|
||||||
MPI_Request request;
|
MPI_Request request;
|
||||||
bool sendData_p = false;
|
bool sendData_p = false;
|
||||||
|
|
||||||
if (info.state == Slice::Fetch) sendData_p = true;
|
if (info.state == Slice<F>::Fetch) sendData_p = true;
|
||||||
// TODO: remove this because I have SelfSufficient
|
// TODO: remove this because I have SelfSufficient
|
||||||
if (otherRank == info.from.rank) sendData_p = false;
|
if (otherRank == info.from.rank) sendData_p = false;
|
||||||
if (!sendData_p) return;
|
if (!sendData_p) return;
|
||||||
|
|
||||||
MPI_Isend( sources[info.from.source].data()
|
MPI_Isend( sources[info.from.source].data()
|
||||||
, sources[info.from.source].size()
|
, sources[info.from.source].size()
|
||||||
, MPI_DOUBLE /* TODO: adapt this with traits */
|
, traits::mpi::datatypeOf<F>()
|
||||||
, otherRank
|
, otherRank
|
||||||
, tag
|
, tag
|
||||||
, universe
|
, universe
|
||||||
@ -1052,19 +1054,19 @@ namespace atrip {
|
|||||||
/**
|
/**
|
||||||
* \brief Receive asynchronously only if the state is Fetch
|
* \brief Receive asynchronously only if the state is Fetch
|
||||||
*/
|
*/
|
||||||
void receive(Slice::Info const& info, size_t tag) noexcept {
|
void receive(typename Slice<F>::Info const& info, size_t tag) noexcept {
|
||||||
auto& slice = Slice::findByInfo(slices, info);
|
auto& slice = Slice<F>::findByInfo(slices, info);
|
||||||
|
|
||||||
if (Atrip::rank == info.from.rank) return;
|
if (Atrip::rank == info.from.rank) return;
|
||||||
|
|
||||||
if (slice.info.state == Slice::Fetch) {
|
if (slice.info.state == Slice<F>::Fetch) {
|
||||||
// TODO: do it through the slice class
|
// TODO: do it through the slice class
|
||||||
slice.info.state = Slice::Dispatched;
|
slice.info.state = Slice<F>::Dispatched;
|
||||||
MPI_Request request;
|
MPI_Request request;
|
||||||
slice.request = request;
|
slice.request = request;
|
||||||
MPI_Irecv( slice.data
|
MPI_Irecv( slice.data
|
||||||
, slice.size
|
, slice.size
|
||||||
, MPI_DOUBLE // TODO: Adapt this with traits
|
, traits::mpi::datatypeOf<F>()
|
||||||
, info.from.rank
|
, info.from.rank
|
||||||
, tag
|
, tag
|
||||||
, universe
|
, universe
|
||||||
@ -1078,42 +1080,42 @@ namespace atrip {
|
|||||||
for (auto type: sliceTypes) unwrapSlice(type, abc);
|
for (auto type: sliceTypes) unwrapSlice(type, abc);
|
||||||
}
|
}
|
||||||
|
|
||||||
F* unwrapSlice(Slice::Type type, ABCTuple const& abc) {
|
F* unwrapSlice(typename Slice<F>::Type type, ABCTuple const& abc) {
|
||||||
WITH_CRAZY_DEBUG
|
WITH_CRAZY_DEBUG
|
||||||
WITH_RANK << "__unwrap__:slice " << type << " w n "
|
WITH_RANK << "__unwrap__:slice " << type << " w n "
|
||||||
<< name
|
<< name
|
||||||
<< " abc" << pretty_print(abc)
|
<< " abc" << pretty_print(abc)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
auto& slice = Slice::findByTypeAbc(slices, type, abc);
|
auto& slice = Slice<F>::findByTypeAbc(slices, type, abc);
|
||||||
WITH_RANK << "__unwrap__:info " << slice.info << "\n";
|
//WITH_RANK << "__unwrap__:info " << slice.info << "\n";
|
||||||
switch (slice.info.state) {
|
switch (slice.info.state) {
|
||||||
case Slice::Dispatched:
|
case Slice<F>::Dispatched:
|
||||||
WITH_RANK << "__unwrap__:Fetch: " << &slice
|
WITH_RANK << "__unwrap__:Fetch: " << &slice
|
||||||
<< " info " << pretty_print(slice.info)
|
<< " info " << pretty_print(slice.info)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
slice.unwrapAndMarkReady();
|
slice.unwrapAndMarkReady();
|
||||||
return slice.data;
|
return slice.data;
|
||||||
break;
|
break;
|
||||||
case Slice::SelfSufficient:
|
case Slice<F>::SelfSufficient:
|
||||||
WITH_RANK << "__unwrap__:SelfSufficient: " << &slice
|
WITH_RANK << "__unwrap__:SelfSufficient: " << &slice
|
||||||
<< " info " << pretty_print(slice.info)
|
<< " info " << pretty_print(slice.info)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
return slice.data;
|
return slice.data;
|
||||||
break;
|
break;
|
||||||
case Slice::Ready:
|
case Slice<F>::Ready:
|
||||||
WITH_RANK << "__unwrap__:READY: UNWRAPPED ALREADY" << &slice
|
WITH_RANK << "__unwrap__:READY: UNWRAPPED ALREADY" << &slice
|
||||||
<< " info " << pretty_print(slice.info)
|
<< " info " << pretty_print(slice.info)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
return slice.data;
|
return slice.data;
|
||||||
break;
|
break;
|
||||||
case Slice::Recycled:
|
case Slice<F>::Recycled:
|
||||||
WITH_RANK << "__unwrap__:RECYCLED " << &slice
|
WITH_RANK << "__unwrap__:RECYCLED " << &slice
|
||||||
<< " info " << pretty_print(slice.info)
|
<< " info " << pretty_print(slice.info)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
return unwrapSlice(slice.info.recycling, abc);
|
return unwrapSlice(slice.info.recycling, abc);
|
||||||
break;
|
break;
|
||||||
case Slice::Fetch:
|
case Slice<F>::Fetch:
|
||||||
case Slice::Acceptor:
|
case Slice<F>::Acceptor:
|
||||||
throw std::domain_error("Can't unwrap an acceptor or fetch slice!");
|
throw std::domain_error("Can't unwrap an acceptor or fetch slice!");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1122,24 +1124,26 @@ namespace atrip {
|
|||||||
return slice.data;
|
return slice.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RankMap rankMap;
|
const RankMap<F> rankMap;
|
||||||
const MPI_Comm world;
|
const MPI_Comm world;
|
||||||
const MPI_Comm universe;
|
const MPI_Comm universe;
|
||||||
const std::vector<size_t> sliceLength;
|
const std::vector<size_t> sliceLength;
|
||||||
std::vector< std::vector<F> > sources;
|
std::vector< std::vector<F> > sources;
|
||||||
std::vector< Slice > slices;
|
std::vector< Slice<F> > slices;
|
||||||
Slice::Name name;
|
typename Slice<F>::Name name;
|
||||||
const std::vector<Slice::Type> sliceTypes;
|
const std::vector<typename Slice<F>::Type> sliceTypes;
|
||||||
std::vector< std::vector<F> > sliceBuffers;
|
std::vector< std::vector<F> > sliceBuffers;
|
||||||
std::set<F*> freePointers;
|
std::set<F*> freePointers;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SliceUnion&
|
template <typename F=double>
|
||||||
unionByName(std::vector<SliceUnion*> const& unions, Slice::Name name) {
|
SliceUnion<F>&
|
||||||
|
unionByName(std::vector<SliceUnion<F>*> const& unions,
|
||||||
|
typename Slice<F>::Name name) {
|
||||||
const auto sliceUnionIt
|
const auto sliceUnionIt
|
||||||
= std::find_if(unions.begin(), unions.end(),
|
= std::find_if(unions.begin(), unions.end(),
|
||||||
[&name](SliceUnion const* s) {
|
[&name](SliceUnion<F> const* s) {
|
||||||
return name == s->name;
|
return name == s->name;
|
||||||
});
|
});
|
||||||
if (sliceUnionIt == unions.end())
|
if (sliceUnionIt == unions.end())
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user