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