MADNESS 0.10.1
Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple Class Reference
Inheritance diagram for madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple:
Inheritance graph
[legend]
Collaboration diagram for madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple:
Collaboration graph
[legend]

Classes

class  MacroTaskPartitionerExchange
 custom partitioning for the exchange operator in exchangeoperator.h More...
 
struct  PrefetchSlot
 One batch requested ahead of the task that will read it. More...
 

Public Types

typedef std::tuple< const std::vector< Function< T, NDIM > > &, const std::vector< Function< T, NDIM > > &, const std::vector< Function< T, NDIM > > & > argtupleT
 
using resultT = std::vector< Function< T, NDIM > >
 

Public Member Functions

 MacroTaskExchangeSimple (const long nresult, const double lo, const double mul_tol, const bool symmetric, const bool owner_pinned=false, const long granularity_level=1, const long universe_rank=0, const int accumulation_mode=2, const bool cost_aware=true, const long batch_salt=0, const bool bra_shares_ket=true, const bool vf_shares_ket=true)
 
void accumulate_locally (World &subworld, const vecfuncT &result_subworld) const
 sum one tile's result into this subworld's accumulator
 
bool accumulates_own_output () const override
 
resultT allocator (World &world, const argtupleT &argtuple) const
 
int bra_role () const
 the record role carrying the bra, and the one carrying the vf over a shared split
 
void cleanup () override
 Drop the cached batches while the subworld holding them is still alive.
 
vecfuncT compute_batch_in_asymmetric_matrix (World &subworld, const vecfuncT &ket_batch, const vecfuncT &bra_batch, const vecfuncT &vf_batch) const
 compute a batch of the exchange matrix, with non-identical ranges
 
vecfuncT compute_diagonal_batch_in_symmetric_matrix (World &subworld, const vecfuncT &ket_batch, const vecfuncT &bra_batch, const vecfuncT &vf_batch) const
 compute a batch of the exchange matrix, with identical ranges, exploiting the matrix symmetry
 
std::pair< vecfuncT, vecfuncTcompute_offdiagonal_batch_in_symmetric_matrix (World &subworld, const vecfuncT &ket_rows, const vecfuncT &ket_columns, const vecfuncT &bra_batch, const vecfuncT &vf_batch) const
 compute a batch of the exchange matrix, with non-identical ranges
 
void ensure_node_accumulator (World &nodeworld) const
 Collectively (re)build the node-shared accumulator in the node world.
 
void finalize_stage1 (World &subworld, World *nodeworld)
 reduce this subworld's accumulator into the node-shared one
 
void finalize_stage2 (World &subworld, World *nodeworld, vecfuncT &universe_result)
 drain into the universe result, from the node accumulator if there is one
 
bool handles_own_data_movement () const override
 the owner-pinned path fetches its operand batches from the cloud itself
 
std::vector< Function< T, NDIM > > operator() (const std::vector< Function< T, NDIM > > &vf_batch, const std::vector< Function< T, NDIM > > &bra_batch, const std::vector< Function< T, NDIM > > &vket)
 
long owner_hint (const Batch &task_batch, const long nsubworld) const override
 
void prepare_owner_assignment (const MacroTaskPartitioner::partitionT &partition, const long nsubworld)
 Assign every task to the rank that will own one of its two batches.
 
bool profile_active () const
 per-task profiling on for this task?
 
void store_batches (World &world, World &subworld, Cloud &cloud, const argtupleT &argtuple, const long nsubworld)
 Store the orbitals as owner-pinned batches, one record per batch.
 
void sym_pipeline_advance (World &subworld, const vecfuncT &, const Batch_1D &next_col, const Batch_1D &next_row, const bool has_next) const
 Request the batch the next task will have to fetch, before computing this one.
 
std::vector< longtouched_result_indices () const
 The result entries this tile actually wrote.
 
int vf_role () const
 
bool wants_node_local_reduction () const
 
- Public Member Functions inherited from madness::MacroTaskOperationBase
 MacroTaskOperationBase ()
 
virtual ~MacroTaskOperationBase ()
 

Static Public Member Functions

static long batch_cache_hits ()
 
static long batch_cache_misses ()
 
static long batch_prefetch_hits ()
 
static void commit_cost_reference ()
 make this call's measured costs the reference for the next one
 
static long cost_matrix_dimension ()
 number of batches this application split into, which squares to the cost matrix
 
static std::vector< double > & cost_this_call ()
 
static long exchange_call_index ()
 
static void reset_batch_cache_counters ()
 

Private Member Functions

void ensure_cache_world (World &world) const
 drop cached batches when the subworld changes; they belong to the old one
 
const vecfuncTfetch_batch (World &world, Cloud &cloud, const long record) const
 Fetch one owner-pinned batch, from the local cache if it is resident.
 

Static Private Member Functions

static void clear_local_caches ()
 
static std::size_t finalize_chunk_entries ()
 entries per chunk in coalesced_gaxpy, sized so one message stays modest at any k
 
static FinalizeReducer< T, NDIM > & get_node_reducer (World &world)
 
static FinalizeReducer< T, NDIM > & get_universe_reducer (World &world)
 

Private Attributes

int accumulation_mode_ = 2
 
long batch_salt_ = 0
 Per-application salt for the batch record keys, from exchange_batch_salt.
 
bool bra_shares_ket_ = true
 
bool cost_aware_ = true
 place tasks by their measured cost rather than by counting them
 
long granularity_level = 1
 
double lo = 1.e-4
 
double mul_tol = 1.e-7
 
long nresult
 
std::map< std::pair< long, long >, longowner_map_
 
bool owner_pinned = false
 pin each task to a rank that owns one of its batches, over the owner-pinned split
 
ExchTaskProfile prof_
 
bool symmetric = false
 
long universe_rank_ = 0
 this process's rank in the universe, to recognise the batches it owns
 
bool vf_shares_ket_ = true
 

Static Private Attributes

static std::map< long, longbatch_begin_to_index_
 batch offset -> index
 
static ExchangeBatchLRU< long, vecfuncTbatch_cache_
 Batches fetched from the cloud, reused across the tasks that run in one subworld.
 
static std::atomic< longbatch_cache_hits_
 
static std::atomic< longbatch_cache_misses_
 
static std::atomic< longbatch_prefetch_hits_
 
static long cache_world_id_ = -1
 
static std::vector< doublecost_reference_
 What each task cost last time, to place them better this time.
 
static std::vector< doublecost_this_call_
 rank-local, summed after the call
 
static long exchange_call_index_ = 0
 
static bool finalize_stage1_done_ = false
 each drain happens once per rank, not once per task object
 
static bool finalize_universe_done_ = false
 
static vecfuncT Kf_local_
 
static bool Kf_local_initialized_ = false
 
static long Kf_local_world_id_ = -1
 
static vecfuncT Kf_node_
 
static bool Kf_node_initialized_ = false
 
static long Kf_node_world_id_ = -1
 
static std::shared_ptr< FinalizeReducer< T, NDIM > > node_reducer_
 
static long node_reducer_world_id_ = -1
 
static PrefetchSlot prefetch_current_
 promoted from the previous task
 
static PrefetchSlot prefetch_next_
 requested during this task
 
static long prof_task_seq_ = 0
 per-process task counter, for identity only
 
static std::shared_ptr< FinalizeReducer< T, NDIM > > universe_reducer_
 Receiving endpoints for the two drains, one per world they transfer within.
 
static long universe_reducer_world_id_ = -1
 

Additional Inherited Members

- Public Attributes inherited from madness::MacroTaskOperationBase
Batch batch
 
Cloudcloud_ptr =0
 
std::string name ="unknown_task"
 
std::shared_ptr< MacroTaskPartitionerpartitioner =0
 
Worldsubworld_ptr =0
 

Member Typedef Documentation

◆ argtupleT

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
typedef std::tuple<const std::vector<Function<T, NDIM> >&, const std::vector<Function<T, NDIM> >&, const std::vector<Function<T, NDIM> >&> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::argtupleT

◆ resultT

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
using madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::resultT = std::vector<Function<T, NDIM> >

Constructor & Destructor Documentation

◆ MacroTaskExchangeSimple()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::MacroTaskExchangeSimple ( const long  nresult,
const double  lo,
const double  mul_tol,
const bool  symmetric,
const bool  owner_pinned = false,
const long  granularity_level = 1,
const long  universe_rank = 0,
const int  accumulation_mode = 2,
const bool  cost_aware = true,
const long  batch_salt = 0,
const bool  bra_shares_ket = true,
const bool  vf_shares_ket = true 
)
inline

References madness::name().

Member Function Documentation

◆ accumulate_locally()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::accumulate_locally ( World subworld,
const vecfuncT result_subworld 
) const
inline

sum one tile's result into this subworld's accumulator

References madness::change_tree_state(), madness::compressed, madness::gaxpy(), madness::World::id(), madness::reconstructed, and madness::TT_FULL.

◆ accumulates_own_output()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::accumulates_own_output ( ) const
inlineoverridevirtual

true if the task sums its own tile results and drains them in the finalize, rather than the queue moving every tile result into the universe result by itself

Reimplemented from madness::MacroTaskOperationBase.

◆ allocator()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
resultT madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::allocator ( World world,
const argtupleT argtuple 
) const
inline

◆ batch_cache_hits()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_cache_hits ( )
inlinestatic

how often a task's operand batch was already resident, and how often it had to be fetched from the rank owning it. No fetches at all means the path never ran.

◆ batch_cache_misses()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_cache_misses ( )
inlinestatic

◆ batch_prefetch_hits()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_prefetch_hits ( )
inlinestatic

◆ bra_role()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
int madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::bra_role ( ) const
inline

the record role carrying the bra, and the one carrying the vf over a shared split

References madness::EXCHANGE_BATCH_BRA, and madness::EXCHANGE_BATCH_KET.

◆ cleanup()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::cleanup ( )
inlineoverridevirtual

Drop the cached batches while the subworld holding them is still alive.

Leaving it to ensure_cache_world to notice a new subworld is too late: by then the cached functions refer to a destroyed world, and merely releasing them walks into it.

Reimplemented from madness::MacroTaskOperationBase.

◆ clear_local_caches()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::clear_local_caches ( )
inlinestaticprivate

◆ commit_cost_reference()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::commit_cost_reference ( )
inlinestatic

make this call's measured costs the reference for the next one

◆ compute_batch_in_asymmetric_matrix()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
vecfuncT madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::compute_batch_in_asymmetric_matrix ( World subworld,
const vecfuncT ket_batch,
const vecfuncT bra_batch,
const vecfuncT vf_batch 
) const
inline

compute a batch of the exchange matrix, with non-identical ranges

Parameters
subworldthe world we're computing in
cloudwhere to store the results
bra_batchthe bra batch of orbitals (including the nuclear correlation factor square)
ket_batchthe ket batch of orbitals, i.e. the orbitals to premultiply with
vf_batchthe argument of the exchange operator

References lo.

◆ compute_diagonal_batch_in_symmetric_matrix()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
vecfuncT madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::compute_diagonal_batch_in_symmetric_matrix ( World subworld,
const vecfuncT ket_batch,
const vecfuncT bra_batch,
const vecfuncT vf_batch 
) const
inline

compute a batch of the exchange matrix, with identical ranges, exploiting the matrix symmetry

Parameters
subworldthe world we're computing in
cloudwhere to store the results
bra_batchthe bra batch of orbitals (including the nuclear correlation factor square)
ket_batchthe ket batch of orbitals, i.e. the orbitals to premultiply with
vf_batchthe argument of the exchange operator Streams the tile one row at a time, so only the intermediates of a single row are live at once where computing the tile in one go holds the whole triangle. Row i builds N_ij = P(bra[i] vf[j]) for j <= i, adds ket[i] N_ij to column j, and adds the mirrored ket[j] N_ij to column i.

References apply(), madness::ExchTaskProfile::apply_wall, madness::compress(), cpu_time(), madness::gaxpy(), lo, MADNESS_CHECK_THROW, madness::ExchTaskProfile::mul1_wall, madness::ExchTaskProfile::mul2_wall, madness::mul_sparse(), truncate(), madness::ExchTaskProfile::truncate_wall, update(), and madness::wall_time().

◆ compute_offdiagonal_batch_in_symmetric_matrix()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::pair< std::vector< Function< T, NDIM > >, std::vector< Function< T, NDIM > > > madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::compute_offdiagonal_batch_in_symmetric_matrix ( World subworld,
const vecfuncT ket_rows,
const vecfuncT ket_columns,
const vecfuncT bra_batch,
const vecfuncT vf_batch 
) const

compute a batch of the exchange matrix, with non-identical ranges

The caller supplies the ket over each of the tile's two ranges: it is the one that knows the ranges, and where those orbitals come from depends on how the operands were supplied, which is not the kernel's concern.

Streams the tile one bra row at a time, so only one row of intermediates is live at once where building the tile in one go holds all nrow*ncolumn of them. Row irow builds N_ij = P(bra[irow] vf[j]) over the whole column range and contributes to both result ranges: ket[irow] N_ij to column j, and the sum over j of ket[j] N_ij to row irow.

Parameters
subworldthe world we're computing in
ket_rowsthe orbitals to premultiply with, over the bra/row range
ket_columnsthe orbitals to premultiply with, over the vf/column range
bra_batchthe bra batch of orbitals (including the nuclear correlation factor square)
vf_batchthe argument of the exchange operator

References madness::apply(), madness::compress(), madness::cpu_time(), madness::dot(), madness::gaxpy(), lo, MADNESS_CHECK_THROW, madness::mul_sparse(), madness::nonlinear_vector_solver(), madness::truncate(), and madness::wall_time().

◆ cost_matrix_dimension()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::cost_matrix_dimension ( )
inlinestatic

number of batches this application split into, which squares to the cost matrix

◆ cost_this_call()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static std::vector< double > & madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::cost_this_call ( )
inlinestatic

◆ ensure_cache_world()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::ensure_cache_world ( World world) const
inlineprivate

drop cached batches when the subworld changes; they belong to the old one

References madness::World::id().

◆ ensure_node_accumulator()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::ensure_node_accumulator ( World nodeworld) const
inline

Collectively (re)build the node-shared accumulator in the node world.

Must be reached by every rank of nodeworld, since constructing a Function is collective; the queue drives this uniformly across the replicated task list, so the initialized flag flips in lockstep. The process map is passed explicitly because the process-wide default is the subworld's during the finalize – inheriting it would map keys to subworld rank indices for functions that live in the node world.

References madness::compressed, madness::WorldGopInterface::fence(), madness::World::gop, and madness::World::id().

◆ exchange_call_index()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::exchange_call_index ( )
inlinestatic

◆ fetch_batch()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
const vecfuncT & madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::fetch_batch ( World world,
Cloud cloud,
const long  record 
) const
inlineprivate

Fetch one owner-pinned batch, from the local cache if it is resident.

A miss goes straight to the owning rank over the cloud's point-to-point batch path. Batches this rank owns are pinned, since every one of its tasks needs them; the others are transient and bounded.

Returns
a reference into the cache, valid until that entry is evicted

References madness::Cloud::batch_owner(), madness::ExchangeBatchLRU< keyT, dataT >::find(), madness::ExchangeBatchLRU< keyT, dataT >::insert(), and madness::ExchTaskProfile::observe_fetch_tier().

◆ finalize_chunk_entries()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static std::size_t madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::finalize_chunk_entries ( )
inlinestaticprivate

entries per chunk in coalesced_gaxpy, sized so one message stays modest at any k

References k, and NDIM.

◆ finalize_stage1()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::finalize_stage1 ( World subworld,
World nodeworld 
)
inline

reduce this subworld's accumulator into the node-shared one

References madness::change_tree_state(), and madness::compressed.

◆ finalize_stage2()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::finalize_stage2 ( World subworld,
World nodeworld,
vecfuncT universe_result 
)
inline

drain into the universe result, from the node accumulator if there is one

References madness::change_tree_state(), and madness::compressed.

◆ get_node_reducer()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static FinalizeReducer< T, NDIM > & madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::get_node_reducer ( World world)
inlinestaticprivate

References madness::World::id().

◆ get_universe_reducer()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static FinalizeReducer< T, NDIM > & madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::get_universe_reducer ( World world)
inlinestaticprivate

One reducer per transport world, rebuilt when that world changes. Collective: constructing a WorldObject is, so every rank of world reaches this together.

References madness::World::id().

◆ handles_own_data_movement()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::handles_own_data_movement ( ) const
inlineoverridevirtual

the owner-pinned path fetches its operand batches from the cloud itself

Reimplemented from madness::MacroTaskOperationBase.

◆ operator()()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::vector< Function< T, NDIM > > madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::operator() ( const std::vector< Function< T, NDIM > > &  vf_batch,
const std::vector< Function< T, NDIM > > &  bra_batch,
const std::vector< Function< T, NDIM > > &  vket 
)
inline

◆ owner_hint()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::owner_hint ( const Batch task_batch,
const long  nsubworld 
) const
inlineoverridevirtual
Returns
the rank this task is pinned to, or -1 to leave the choice to the queue

Reimplemented from madness::MacroTaskOperationBase.

References madness::Batch::input, and MADNESS_CHECK_THROW.

◆ prepare_owner_assignment()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::prepare_owner_assignment ( const MacroTaskPartitioner::partitionT partition,
const long  nsubworld 
)
inline

Assign every task to the rank that will own one of its two batches.

Called by the macrotask queue after partitioning and before it asks for each task's owner. The batch boundaries come from the same split the partitioner used, so a task's (column, row) batch offsets identify a pair of batch indices, and exchange_sym_round_robin_assign turns that pair into an owner. Every rank runs this over the same partition and gets the same map without communicating.

References c, madness::exchange_row_owner_assign(), madness::exchange_sym_cost_aware_assign(), madness::exchange_sym_owner_split(), madness::exchange_sym_round_robin_assign(), k, MADNESS_CHECK_THROW, and split().

◆ profile_active()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::profile_active ( ) const
inline

per-task profiling on for this task?

References madness::exch_task_profile_enabled().

◆ reset_batch_cache_counters()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
static void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::reset_batch_cache_counters ( )
inlinestatic

◆ store_batches()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::store_batches ( World world,
World subworld,
Cloud cloud,
const argtupleT argtuple,
const long  nsubworld 
)
inline

Store the orbitals as owner-pinned batches, one record per batch.

Called by the macrotask queue on the universe right after the argument tuple is stored. The batch boundaries and the record keys are derived exactly as the task side derives them, so no manifest has to be communicated.

Every rank registers the routing for all records, which is local and needs no communication, and then each owner pulls the batches it owns into its own size-1 subworld and serializes them there. That is what spreads the ingest across the owners: serializing centrally instead funnels the whole orbital set through one rank's network interface.

A record is stored per distinct operand vector, not per role: HF exchange passes one vector as all three and still stores a single set, nemo's bra = R^2 * ket makes two, and three only when all three differ. The symmetric grid shares one split; the asymmetric one puts vf on the column boundaries and bra/ket on the row ones, so vf needs its own record there even when it is the ket.

References madness::Batch_1D::begin, copy(), madness::Batch_1D::end, madness::EXCHANGE_BATCH_BRA, madness::EXCHANGE_BATCH_KET, madness::exchange_batch_record_key(), madness::EXCHANGE_BATCH_VF, madness::exchange_row_owner_split(), madness::exchange_sym_owner_split(), madness::WorldGopInterface::fence(), madness::World::gop, k, MADNESS_CHECK_THROW, madness::World::rank(), madness::Cloud::register_batch_owner(), madness::Batch_1D::size(), madness::World::size(), split(), madness::Cloud::store_batch(), and v.

◆ sym_pipeline_advance()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
void madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::sym_pipeline_advance ( World subworld,
const vecfuncT ,
const Batch_1D next_col,
const Batch_1D next_row,
const bool  has_next 
) const
inline

Request the batch the next task will have to fetch, before computing this one.

Called by the queue once per task, before the task body, with the batches of the next task this rank will run. Of that task's two batches one is normally owned here and reads locally, so at most one is worth requesting – and requesting exactly one keeps the in-flight count within the bound PrefetchSlot documents.

This is what makes the owner-pinned transport worth its machinery: without it every task pays the full latency of its remote batch with nothing to overlap it against.

Parameters
mo_ketunused: the salt it used to be derived from is carried on the task. It stays in the signature because the queue's detection trait matches on it (has_sym_pipeline_advance_v).

References madness::Cloud::batch_owner(), madness::ExchangeBatchLRU< keyT, dataT >::contains(), madness::EXCHANGE_BATCH_KET, madness::exchange_batch_record_key(), madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::PrefetchSlot::fut, madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::PrefetchSlot::key, madness::Cloud::request_batch_bytes_async(), and madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::PrefetchSlot::valid.

◆ touched_result_indices()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::vector< long > madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::touched_result_indices ( ) const
inline

The result entries this tile actually wrote.

operator() scatters into a full-width Kf and leaves everything else zero, so summing all nresult entries would gaxpy mostly zeros – a per-tile cost proportional to the whole result vector. Every tile writes its column range; a symmetric off-diagonal tile also writes its row range, reusing each intermediate for the transposed element, whereas an asymmetric tile contributes to its column alone. A full-size or absent range falls back to all of them.

The result must be a set: the caller gaxpys one entry per index, so a repeated index is added twice. The two ranges do overlap in the asymmetric case, coming from separate splits of different lengths rather than from one split, where they are always equal or disjoint.

References b, and e().

◆ vf_role()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
int madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::vf_role ( ) const
inline

◆ wants_node_local_reduction()

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::wants_node_local_reduction ( ) const
inline

true if the drain goes subworld -> node -> universe rather than straight to the universe, so only one rank per node scatters across nodes not an override: the queue reaches this through its optional-hook detection, since the virtual it feeds lives on the internal task rather than on this base

Member Data Documentation

◆ accumulation_mode_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
int madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::accumulation_mode_ = 2
private

1 = sum into a subworld buffer and drain that into the universe; 2 = additionally reduce within a node first, so only one rank per node scatters across nodes. Degrades to 1 automatically when there is a single node.

◆ batch_begin_to_index_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::map<long,long> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_begin_to_index_
inlinestaticprivate

batch offset -> index

◆ batch_cache_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
ExchangeBatchLRU<long, vecfuncT> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_cache_
inlinestaticprivate

Batches fetched from the cloud, reused across the tasks that run in one subworld.

Static because the tasks of a subworld are separate objects: the cache has to outlive any one of them to be reused at all. It is therefore scoped by hand to the subworld that filled it – see ensure_cache_world, which drops it when the subworld changes so a batch from one subworld is never read in another.

◆ batch_cache_hits_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::atomic<long> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_cache_hits_
inlinestaticprivate

◆ batch_cache_misses_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::atomic<long> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_cache_misses_
inlinestaticprivate

◆ batch_prefetch_hits_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::atomic<long> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_prefetch_hits_
inlinestaticprivate

◆ batch_salt_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::batch_salt_ = 0
private

Per-application salt for the batch record keys, from exchange_batch_salt.

Carried on the task rather than re-derived where it is used: every rank builds the same task objects collectively, so a constructor argument already reaches every rank, and deriving it instead requires whichever operand vector it is taken from to be available in full wherever a key is formed. That is true only while the ket is passed unbatched.

◆ bra_shares_ket_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::bra_shares_ket_ = true
private

Which role's record actually carries the bra and the vf. Identical operand vectors share one stored record instead of duplicating coefficients: HF exchange passes one vector as all three operands, nemo passes one as ket and vf. Set on the universe side, where all three are in hand; see exchange_same_operands.

◆ cache_world_id_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::cache_world_id_ = -1
inlinestaticprivate

◆ cost_aware_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::cost_aware_ = true
private

place tasks by their measured cost rather than by counting them

◆ cost_reference_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::vector<double> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::cost_reference_
inlinestaticprivate

What each task cost last time, to place them better this time.

Screening makes the tiles strongly uneven for large molecules, and a placement that balances task counts cannot see that. The measured wall time of each tile is recorded here, summed across ranks after the call – each tile ran on exactly one rank, so summing unions the contributions – and used as the reference for the next call. Kept across calls and across protocol changes on purpose: only the relative cost matters, and its structure barely moves between them. from the previous call

◆ cost_this_call_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::vector<double> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::cost_this_call_
inlinestaticprivate

rank-local, summed after the call

◆ exchange_call_index_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::exchange_call_index_ = 0
inlinestaticprivate

◆ finalize_stage1_done_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::finalize_stage1_done_ = false
inlinestaticprivate

each drain happens once per rank, not once per task object

◆ finalize_universe_done_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::finalize_universe_done_ = false
inlinestaticprivate

◆ granularity_level

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::granularity_level = 1
private

◆ Kf_local_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
vecfuncT madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::Kf_local_
inlinestaticprivate

Where this subworld's tile results are summed before they leave it, and where a node's subworlds are summed before that leaves the node. Static for the same reason the batch cache is – each task batch is a separate object – and so subject to the same two lifetime rules: the world-id guards below stop a stale read, and cleanup() releases them while their world is still alive. Neither alone is enough.

◆ Kf_local_initialized_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::Kf_local_initialized_ = false
inlinestaticprivate

◆ Kf_local_world_id_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::Kf_local_world_id_ = -1
inlinestaticprivate

◆ Kf_node_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
vecfuncT madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::Kf_node_
inlinestaticprivate

◆ Kf_node_initialized_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::Kf_node_initialized_ = false
inlinestaticprivate

◆ Kf_node_world_id_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::Kf_node_world_id_ = -1
inlinestaticprivate

◆ lo

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
double madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::lo = 1.e-4
private

◆ mul_tol

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
double madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::mul_tol = 1.e-7
private

◆ node_reducer_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::shared_ptr<FinalizeReducer<T, NDIM> > madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::node_reducer_
inlinestaticprivate

◆ node_reducer_world_id_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::node_reducer_world_id_ = -1
inlinestaticprivate

◆ nresult

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::nresult
private

◆ owner_map_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::map<std::pair<long,long>,long> madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::owner_map_
private

(column batch offset, row batch offset) -> owning rank, filled by prepare_owner_assignment and read by owner_hint

◆ owner_pinned

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::owner_pinned = false
private

pin each task to a rank that owns one of its batches, over the owner-pinned split

◆ prefetch_current_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
PrefetchSlot madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::prefetch_current_
inlinestaticprivate

promoted from the previous task

◆ prefetch_next_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
PrefetchSlot madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::prefetch_next_
inlinestaticprivate

requested during this task

◆ prof_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
ExchTaskProfile madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::prof_
mutableprivate

This task's profile record. NOT static: it belongs to the single operator() call on this object, and the fetch writes into it through this during that call.

◆ prof_task_seq_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::prof_task_seq_ = 0
inlinestaticprivate

per-process task counter, for identity only

◆ symmetric

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::symmetric = false
private

◆ universe_rank_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::universe_rank_ = 0
private

this process's rank in the universe, to recognise the batches it owns

◆ universe_reducer_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
std::shared_ptr<FinalizeReducer<T, NDIM> > madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::universe_reducer_
inlinestaticprivate

Receiving endpoints for the two drains, one per world they transfer within.

These are WorldObjects, so they are bound to a world exactly as a Function is, and the same lifetime rule applies: release them while that world is still alive. The node world is built per application (the queue owns it and a fresh queue is built per call), so a cached node reducer that survives the application is registered in a world that no longer exists. The world id is kept beside the pointer rather than read back out of it, because comparing reducer->get_world().id() is itself a read of the dead world.

◆ universe_reducer_world_id_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
long madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::universe_reducer_world_id_ = -1
inlinestaticprivate

◆ vf_shares_ket_

template<typename T , std::size_t NDIM>
template<typename T , std::size_t NDIM>
bool madness::Exchange< T, NDIM >::ExchangeImpl< T, NDIM >::MacroTaskExchangeSimple::vf_shares_ket_ = true
private

The documentation for this class was generated from the following files: