Add tentative DatabaseCommunicator
This commit is contained in:
parent
1e391e3749
commit
118df09128
20
include/atrip/DatabaseCommunicator.hpp
Normal file
20
include/atrip/DatabaseCommunicator.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <atrip/Utils.hpp>
|
||||||
|
#include <atrip/Equations.hpp>
|
||||||
|
#include <atrip/SliceUnion.hpp>
|
||||||
|
#include <atrip/Unions.hpp>
|
||||||
|
|
||||||
|
namespace atrip {
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
using Unions = std::vector<SliceUnion<F>*>;
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
typename Slice<F>::Database
|
||||||
|
naiveDatabase(Unions<F> &unions,
|
||||||
|
size_t nv,
|
||||||
|
size_t np,
|
||||||
|
size_t iteration,
|
||||||
|
MPI_Comm const& c);
|
||||||
|
|
||||||
|
} // namespace atrip
|
||||||
@ -7,7 +7,7 @@ AM_CPPFLAGS = $(CTF_CPPFLAGS)
|
|||||||
lib_LIBRARIES = libatrip.a
|
lib_LIBRARIES = libatrip.a
|
||||||
|
|
||||||
libatrip_a_CPPFLAGS = -I$(top_srcdir)/include/
|
libatrip_a_CPPFLAGS = -I$(top_srcdir)/include/
|
||||||
libatrip_a_SOURCES = ./atrip/Blas.cxx ./atrip/Tuples.cxx
|
libatrip_a_SOURCES = ./atrip/Blas.cxx ./atrip/Tuples.cxx ./atrip/DatabaseCommunicator.cxx
|
||||||
NVCC_FILES = ./atrip/Equations.cxx ./atrip/Complex.cxx ./atrip/Atrip.cxx
|
NVCC_FILES = ./atrip/Equations.cxx ./atrip/Complex.cxx ./atrip/Atrip.cxx
|
||||||
|
|
||||||
if WITH_CUDA
|
if WITH_CUDA
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include <atrip/SliceUnion.hpp>
|
#include <atrip/SliceUnion.hpp>
|
||||||
#include <atrip/Unions.hpp>
|
#include <atrip/Unions.hpp>
|
||||||
#include <atrip/Checkpoint.hpp>
|
#include <atrip/Checkpoint.hpp>
|
||||||
|
#include <atrip/DatabaseCommunicator.hpp>
|
||||||
|
|
||||||
using namespace atrip;
|
using namespace atrip;
|
||||||
#if defined(HAVE_CUDA)
|
#if defined(HAVE_CUDA)
|
||||||
@ -299,9 +300,16 @@ Atrip::Output Atrip::run(Atrip::Input<F> const& in) {
|
|||||||
using Database = typename Slice<F>::Database;
|
using Database = typename Slice<F>::Database;
|
||||||
auto communicateDatabase
|
auto communicateDatabase
|
||||||
= [ &unions
|
= [ &unions
|
||||||
|
, &in
|
||||||
|
, Nv
|
||||||
, np
|
, np
|
||||||
] (ABCTuple const& abc, MPI_Comm const& c) -> Database {
|
] (ABCTuple const& abc, MPI_Comm const& c, size_t iteration) -> Database {
|
||||||
|
|
||||||
|
if (in.tuplesDistribution == Atrip::Input<F>::TuplesDistribution::NAIVE) {
|
||||||
|
|
||||||
|
return naiveDatabase<F>(unions, Nv, np, iteration, c);
|
||||||
|
|
||||||
|
} else {
|
||||||
WITH_CHRONO("db:comm:type:do",
|
WITH_CHRONO("db:comm:type:do",
|
||||||
auto MPI_LDB_ELEMENT = Slice<F>::mpi::localDatabaseElement();
|
auto MPI_LDB_ELEMENT = Slice<F>::mpi::localDatabaseElement();
|
||||||
)
|
)
|
||||||
@ -334,6 +342,8 @@ Atrip::Output Atrip::run(Atrip::Input<F> const& in) {
|
|||||||
WITH_CHRONO("db:comm:type:free", MPI_Type_free(&MPI_LDB_ELEMENT);)
|
WITH_CHRONO("db:comm:type:free", MPI_Type_free(&MPI_LDB_ELEMENT);)
|
||||||
|
|
||||||
return db;
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto doIOPhase
|
auto doIOPhase
|
||||||
@ -564,7 +574,7 @@ Atrip::Output Atrip::run(Atrip::Input<F> const& in) {
|
|||||||
// COMM FIRST DATABASE ================================================{{{1
|
// COMM FIRST DATABASE ================================================{{{1
|
||||||
if (i == first_iteration) {
|
if (i == first_iteration) {
|
||||||
WITH_RANK << "__first__:first database ............ \n";
|
WITH_RANK << "__first__:first database ............ \n";
|
||||||
const auto db = communicateDatabase(abc, universe);
|
const auto db = communicateDatabase(abc, universe, i);
|
||||||
WITH_RANK << "__first__:first database communicated \n";
|
WITH_RANK << "__first__:first database communicated \n";
|
||||||
WITH_RANK << "__first__:first database io phase \n";
|
WITH_RANK << "__first__:first database io phase \n";
|
||||||
doIOPhase(db);
|
doIOPhase(db);
|
||||||
@ -579,7 +589,7 @@ Atrip::Output Atrip::run(Atrip::Input<F> const& in) {
|
|||||||
if (abcNext) {
|
if (abcNext) {
|
||||||
WITH_RANK << "__comm__:" << iteration << "th communicating database\n";
|
WITH_RANK << "__comm__:" << iteration << "th communicating database\n";
|
||||||
WITH_CHRONO("db:comm",
|
WITH_CHRONO("db:comm",
|
||||||
const auto db = communicateDatabase(*abcNext, universe);
|
const auto db = communicateDatabase(*abcNext, universe, i);
|
||||||
)
|
)
|
||||||
WITH_CHRONO("db:io",
|
WITH_CHRONO("db:io",
|
||||||
doIOPhase(db);
|
doIOPhase(db);
|
||||||
|
|||||||
167
src/atrip/DatabaseCommunicator.cxx
Normal file
167
src/atrip/DatabaseCommunicator.cxx
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
#include <atrip/DatabaseCommunicator.hpp>
|
||||||
|
#include <atrip/Complex.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace atrip {
|
||||||
|
|
||||||
|
static
|
||||||
|
ABCTuples get_nth_naive_tuples(size_t Nv, size_t np) {
|
||||||
|
|
||||||
|
const size_t
|
||||||
|
// total number of tuples for the problem
|
||||||
|
n = Nv * (Nv + 1) * (Nv + 2) / 6 - Nv
|
||||||
|
|
||||||
|
// all ranks should have the same number of tuples_per_rank
|
||||||
|
, tuples_per_rank = n / np + size_t(n % np != 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
ABCTuples result(np);
|
||||||
|
|
||||||
|
for (size_t a(0), g(0); a < Nv; a++)
|
||||||
|
for (size_t b(a); b < Nv; b++)
|
||||||
|
for (size_t c(b); c < Nv; c++){
|
||||||
|
if ( a == b && b == c ) continue;
|
||||||
|
for (size_t rank = 0; rank < np; rank++) {
|
||||||
|
|
||||||
|
const size_t
|
||||||
|
// start index for the global tuples list
|
||||||
|
start = tuples_per_rank * rank
|
||||||
|
|
||||||
|
// end index for the global tuples list
|
||||||
|
, end = tuples_per_rank * (rank + 1)
|
||||||
|
;
|
||||||
|
|
||||||
|
if ( start <= g && g < end) result[rank] = {a, b, c};
|
||||||
|
|
||||||
|
}
|
||||||
|
g++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
static
|
||||||
|
typename Slice<F>::LocalDatabase
|
||||||
|
build_local_database_fake(ABCTuple const& abc_prev,
|
||||||
|
ABCTuple const& abc,
|
||||||
|
size_t rank,
|
||||||
|
SliceUnion<F>* u) {
|
||||||
|
|
||||||
|
typename Slice<F>::LocalDatabase result;
|
||||||
|
|
||||||
|
// vector of type x tuple
|
||||||
|
auto const needed = u->neededSlices(abc);
|
||||||
|
auto const needed_prev = u->neededSlices(abc_prev);
|
||||||
|
|
||||||
|
for (auto const& pair: needed) {
|
||||||
|
auto const type = pair.first;
|
||||||
|
auto const tuple = pair.second;
|
||||||
|
auto const from = u->rankMap.find(abc, type);
|
||||||
|
|
||||||
|
// Try to find in the previously needed slices
|
||||||
|
// one that exactly matches the tuple.
|
||||||
|
// Not necessarily has to match the type.
|
||||||
|
//
|
||||||
|
// If we find it, then it means that the fake rank
|
||||||
|
// will mark it as recycled. This covers
|
||||||
|
// the finding of Ready slices and Recycled slices.
|
||||||
|
{
|
||||||
|
auto const& it
|
||||||
|
= std::find_if(needed_prev.begin(), needed_prev.end(),
|
||||||
|
[&tuple, &type](typename Slice<F>::Ty_x_Tu const& o) {
|
||||||
|
return o.second == tuple;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it != needed_prev.end()) {
|
||||||
|
typename Slice<F>::Info info;
|
||||||
|
info.tuple = tuple;
|
||||||
|
info.type = type;
|
||||||
|
info.from = from;
|
||||||
|
info.state = Slice<F>::Recycled;
|
||||||
|
result.push_back({u->name, info});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
typename Slice<F>::Info info;
|
||||||
|
info.type = type;
|
||||||
|
info.tuple = tuple;
|
||||||
|
info.from = from;
|
||||||
|
|
||||||
|
// Handle self sufficiency
|
||||||
|
info.state = rank == from.rank
|
||||||
|
? Slice<F>::SelfSufficient
|
||||||
|
: Slice<F>::Fetch
|
||||||
|
;
|
||||||
|
result.push_back({u->name, info});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
typename Slice<F>::Database
|
||||||
|
naiveDatabase(Unions<F> &unions,
|
||||||
|
size_t nv,
|
||||||
|
size_t np,
|
||||||
|
size_t iteration,
|
||||||
|
MPI_Comm const& c) {
|
||||||
|
|
||||||
|
using Database = typename Slice<F>::Database;
|
||||||
|
Database db;
|
||||||
|
const auto tuples = get_nth_naive_tuples(nv, np);
|
||||||
|
const auto prev_tuples = get_nth_naive_tuples(nv, np);
|
||||||
|
|
||||||
|
for (size_t rank = 0; rank < np; rank++) {
|
||||||
|
auto abc = tuples[rank];
|
||||||
|
typename Slice<F>::LocalDatabase ldb;
|
||||||
|
|
||||||
|
for (auto const& tensor: unions) {
|
||||||
|
if (rank == Atrip::rank) {
|
||||||
|
auto const& tensorDb = tensor->buildLocalDatabase(abc);
|
||||||
|
ldb.insert(ldb.end(), tensorDb.begin(), tensorDb.end());
|
||||||
|
} else {
|
||||||
|
auto const& tensorDb
|
||||||
|
= build_local_database_fake(prev_tuples[rank],
|
||||||
|
abc,
|
||||||
|
rank,
|
||||||
|
tensor);
|
||||||
|
ldb.insert(ldb.end(), tensorDb.begin(), tensorDb.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db.insert(db.end(), ldb.begin(), ldb.end());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
template
|
||||||
|
typename Slice<double>::Database
|
||||||
|
naiveDatabase<double>(Unions<double> &unions,
|
||||||
|
size_t nv,
|
||||||
|
size_t np,
|
||||||
|
size_t iteration,
|
||||||
|
MPI_Comm const& c);
|
||||||
|
|
||||||
|
template
|
||||||
|
typename Slice<Complex>::Database
|
||||||
|
naiveDatabase<Complex>(Unions<Complex> &unions,
|
||||||
|
size_t nv,
|
||||||
|
size_t np,
|
||||||
|
size_t iteration,
|
||||||
|
MPI_Comm const& c);
|
||||||
|
|
||||||
|
} // namespace atrip
|
||||||
Loading…
Reference in New Issue
Block a user