25#ifndef __SPLINDEX_HPP__
26#define __SPLINDEX_HPP__
38 return (length__ / block_size__) + std::min(length__ % block_size__, 1);
50 block_size__ = length__ / nb + std::min(1, length__ % nb);
52 std::vector<int> result(nb);
54 for (
int i = 0; i < nb; i++) {
55 result[i] = std::min(length__, (i + 1) * block_size__) - i * block_size__;
58 if (std::accumulate(result.begin(), result.end(), 0) != length__) {
59 throw std::runtime_error(
"error in sirius::split_in_blocks()");
66template <
typename T =
int>
75 typedef int value_type;
81 typedef int value_type;
87 typedef int value_type;
93 typedef int value_type;
99 typedef int value_type;
119template <
typename Index_t = basic_index_t<
int>>
123 using value_type =
typename Index_t::value_type;
162 s <<
"wrong size : " << size__;
163 throw std::runtime_error(s.str());
165 this->
size_ = size__;
167 if (n_blocks__.get() < 0) {
169 s <<
"wrong number of blocks : " << n_blocks__.get();
170 throw std::runtime_error(s.str());
174 if (block_id__.get() < 0 || block_id__.get() >= n_blocks__.get()) {
176 s <<
"wrong rank block id : " << block_id__.get();
177 throw std::runtime_error(s.str());
193 virtual typename Index_t::global
global_index(
typename Index_t::local idxloc__,
block_id block_id__)
const = 0;
207 inline auto global_index(
typename Index_t::local idxloc__)
const
213 inline auto size() const noexcept
221 return size__ / n_blocks__ + std::min(value_type(1), size__ % n_blocks__);
225template <
typename Index_t>
231 using difference_type = std::ptrdiff_t;
232 typename Index_t::local li;
244 return this->li != rhs__.li;
260 inline auto operator*()
263 typename Index_t::global i;
264 typename Index_t::local li; } ret{idx_->
global_index(this->li), this->li};
270 return li - rhs__.li;
280template <
typename Index_t = basic_index_t<
int>>
294 :
splindex<Index_t>(size__, n_blocks__, block_id__)
296 this->block_size_ = this->
block_size(size__, n_blocks__);
304 RTE_ASSERT(block_id__ >= 0 && block_id__ < this->
n_blocks_);
306 if (this->
size_ == 0) {
311 if (block_id__ < n) {
321 RTE_ASSERT(idx__ < this->
size_);
323 auto ib =
static_cast<int>(idx__ / this->
block_size_);
324 value_type idxloc = idx__ - ib * this->
block_size_;
334 RTE_ASSERT(block_id__ >= 0 && block_id__ < this->
n_blocks_);
337 return typename Index_t::global(-1);
340 RTE_ASSERT(idxloc__ <
local_size(block_id__));
342 return typename Index_t::global(this->block_size_ * block_id__ + idxloc__);
345 inline auto global_offset()
const
350 inline auto global_offset(
block_id iblock__)
const
352 return this->
global_index(
typename Index_t::local(0), iblock__);
355 inline auto counts()
const
357 std::vector<value_type> v(this->
n_blocks_);
358 for (
int i = 0; i < this->
n_blocks_; i++) {
365template <
typename Index_t = basic_index_t<
int>>
379 :
splindex<Index_t>(size__, n_blocks__, block_id__)
389 RTE_ASSERT(block_id__ >= 0 && block_id__ < this->
n_blocks_);
391 if (this->
size_ == 0) {
400 if (block_id__ < rank_offs) {
402 }
else if (block_id__ == rank_offs) {
411 RTE_ASSERT(idx__ < this->
size_);
417 value_type idxloc = (
num_blocks / this->
n_blocks_) * block_size_ + idx__ % this->block_size_;
430 RTE_ASSERT(block_id__ >= 0 && block_id__ < this->
n_blocks_);
431 RTE_ASSERT(idxloc__ <
local_size(block_id__));
435 return typename Index_t::global((nb * this->n_blocks_ + block_id__) * this->block_size_ +
436 idxloc__ % this->block_size_);
442template <
typename Index_t = basic_index_t<
int>>
448 std::vector<std::vector<value_type>> global_index_;
449 std::vector<typename splindex<Index_t>::location_t> locations_;
459 :
splindex<Index_t>(size__, n_blocks__, block_id__)
461 for (
int r = 0; r < n_blocks__.get(); r++) {
462 global_index_.push_back(std::vector<value_type>());
463 for (value_type i = 0; i < counts__[r]; i++) {
464 global_index_.back().push_back(
static_cast<value_type
>(locations_.size()));
469 RTE_ASSERT(
static_cast<value_type
>(locations_.size()) == this->size());
476 RTE_ASSERT(block_id__ >= 0 && block_id__ < this->
n_blocks_);
478 if (this->
size_ == 0) {
481 return static_cast<value_type
>(global_index_[block_id__].size());
486 return locations_[idx__];
493 RTE_ASSERT(block_id__ >= 0 && block_id__ < this->
n_blocks_);
494 RTE_ASSERT(idxloc__ <
local_size(block_id__));
496 return typename Index_t::global(global_index_[block_id__][idxloc__]);
499 inline auto global_offset()
const
505template <
typename Index_t>
506auto begin_global(splindex<Index_t>
const& a__)
508 return typename Index_t::global(0);
511template <
typename Index_t>
512auto end_global(splindex<Index_t>
const& a__)
514 return typename Index_t::global(a__.size());
517template <
typename Index_t>
518auto begin(splindex<Index_t>
const& a__)
520 splindex_iterator_t<Index_t> it(a__);
521 it.li =
typename Index_t::local(0);
525template <
typename Index_t>
526auto end(splindex<Index_t>
const& a__)
528 splindex_iterator_t<Index_t> it(a__);
529 it.li =
typename Index_t::local(a__.local_size());
value_type block_size_
Cyclic block size.
Index_t::global global_index(typename Index_t::local idxloc__, block_id block_id__) const
Return global index of an element by local index and block id.
splindex< Index_t >::location_t location(typename Index_t::global idx__) const
Return "local index, rank" pair for a global index.
value_type local_size(block_id block_id__) const
Return local size of the split index for a given block.
splindex_block_cyclic(value_type size__, n_blocks n_blocks__, block_id block_id__, value_type block_size__)
Constructor.
value_type local_size(block_id block_id__) const
Return local size of the split index for a given block.
value_type block_size_
Local index size of a given block.
splindex< Index_t >::location_t location(typename Index_t::global idx__) const
Return "local index, rank" pair for a global index.
Index_t::global global_index(typename Index_t::local idxloc__, block_id block_id__) const
Return global index of an element by local index and block id.
splindex_block(value_type size__, n_blocks n_blocks__, block_id block_id__)
Constructor.
Externally defined block distribution.
splindex< Index_t >::location_t location(typename Index_t::global idx__) const
Return location (block_id and local offset) of the global index.
splindex_chunk()
Default constructor.
splindex_chunk(value_type size__, n_blocks n_blocks__, block_id block_id__, std::vector< value_type > const counts__)
Constructor with specific partitioning.
Index_t::global global_index(typename Index_t::local idxloc__, block_id block_id__) const
Return global index by block id and local index.
value_type local_size(block_id block_id__) const
Return local size of the split index for a given block.
Base class for split index.
value_type local_size() const
Return local size for the current block.
n_blocks n_blocks_
Number of blocks over which the global index is distributed.
virtual Index_t::global global_index(typename Index_t::local idxloc__, block_id block_id__) const =0
Return global index by block id and local index.
splindex(value_type size__, n_blocks n_blocks__, block_id block_id__)
Constructor.
auto global_index(typename splindex< Index_t >::location_t loc__) const
Return global index of an element by local index and block id.
value_type size_
Size (aka length) of the global index.
splindex()
Default constructor.
virtual value_type local_size(block_id block_id__) const =0
Return local size of the split index for a given block.
static auto block_size(value_type size__, n_blocks n_blocks__)
Compute size of the block from global index size and number of blocks.
virtual location_t location(typename Index_t::global idx__) const =0
Return location (block_id and local offset) of the global index.
block_id block_id_
Index of the block with local fraction of the global index.
auto size() const noexcept
Return total length of the index (global number of elements).
Namespace of the SIRIUS library.
int num_blocks(int length__, int block_size__)
Return the maximum number of blocks (with size 'block_size') needed to split the 'length' elements.
auto split_in_blocks(int length__, int block_size__)
Split the 'length' elements into blocks with the initial block size.
strong_type< int, struct __block_id_tag > block_id
ID of the block.
Eror and warning handling during run-time execution.
A wrapper class to create strong types.
Pair of <local index, block_id> describing the location of a global index element.
block_id ib
Index of the block.
location_t(typename Index_t::local index_local__, block_id ib__)
Constructor.
Index_t::local index_local
Local index inside a block.