Program Listing for File distributed_iterator_traits.h¶
↰ Return to documentation for file (include/shad/distributed_iterator_traits.h
)
//===------------------------------------------------------------*- C++ -*-===//
//
// SHAD
//
// The Scalable High-performance Algorithms and Data Structure Library
//
//===----------------------------------------------------------------------===//
//
// Copyright 2018 Battelle Memorial Institute
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
//
//===----------------------------------------------------------------------===//
#ifndef INCLUDE_SHAD_DISTRIBUTED_ITERATOR_TRAIT_H
#define INCLUDE_SHAD_DISTRIBUTED_ITERATOR_TRAIT_H
#include <cassert>
#include <iterator>
#include <vector>
#include "shad/runtime/locality.h"
namespace shad {
template <typename Iterator>
struct distributed_iterator_traits : public std::iterator_traits<Iterator> {
using difference_type =
typename std::iterator_traits<Iterator>::difference_type;
using value_type = typename std::iterator_traits<Iterator>::value_type;
using pointer = typename std::iterator_traits<Iterator>::pointer;
using reference = typename std::iterator_traits<Iterator>::reference;
using iterator_category =
typename std::iterator_traits<Iterator>::iterator_category;
using local_iterator_range = typename Iterator::local_iterator_range;
using local_iterator_type = typename Iterator::local_iterator_type;
static rt::localities_range localities(Iterator begin, Iterator end) {
return Iterator::localities(begin, end);
}
static local_iterator_range local_range(Iterator begin, Iterator end) {
return Iterator::local_range(begin, end);
}
static Iterator iterator_from_local(Iterator begin, Iterator end,
local_iterator_type itr) {
return Iterator::iterator_from_local(begin, end, itr);
}
};
template <typename T, typename = void>
struct is_distributed_iterator {
static constexpr bool value = false;
};
template <typename T>
struct is_distributed_iterator<
T, typename std::enable_if<
!std::is_same<typename distributed_iterator_traits<T>::value_type,
void>::value>::type> {
static constexpr bool value = true;
};
template <typename Iterator>
struct distributed_random_access_iterator_trait
: public distributed_iterator_traits<Iterator> {
using value_type = typename distributed_iterator_traits<Iterator>::value_type;
using pointer = typename distributed_iterator_traits<Iterator>::pointer;
using reference = typename distributed_iterator_traits<Iterator>::reference;
using iterator_category =
typename distributed_iterator_traits<Iterator>::iterator_category;
using distribution_range = typename Iterator::distribution_range;
static distribution_range distribution(Iterator begin, Iterator end) {
return Iterator::distribution(begin, end);
}
};
// support for partitioning of local ranges
template <typename Iterator>
struct local_iterator_traits : public std::iterator_traits<Iterator> {
// split a range into n non-empty sub-ranges
static std::vector<typename Iterator::partition_range> partitions(
Iterator begin, Iterator end, size_t n) {
return Iterator::partitions(begin, end, n);
}
};
// specialization for raw pointers (e.g., array, vector)
template <typename T>
class local_iterator_traits<T *> {
public:
class partition_range {
public:
T *begin() { return begin_; }
T *end() { return end_; }
partition_range(T *begin, T *end) : begin_(begin), end_(end) {}
private:
T *begin_;
T *end_;
};
// split a range into at most n sub-ranges
static std::vector<partition_range> partitions(T *begin, T *end, size_t n) {
auto range_len = std::distance(begin, end);
auto n_parts = std::min(n, static_cast<size_t>(range_len));
std::vector<partition_range> res;
if (n_parts) {
auto block_size = (range_len + n_parts - 1) / n_parts;
for (size_t block_id = 0; block_id < n_parts; ++block_id) {
auto block_begin = begin;
std::advance(block_begin, block_id * block_size);
auto block_end = block_begin;
if (std::distance(block_begin, end) < block_size) {
if (block_begin != end) {
res.push_back(partition_range{block_begin, end});
}
break;
} else {
std::advance(block_end, block_size);
assert(block_begin != block_end);
res.push_back(partition_range{block_begin, block_end});
}
}
assert(res.back().end() == end);
}
return res;
}
};
} // namespace shad
#endif /* INCLUDE_SHAD_DISTRIBUTED_ITERATOR_TRAIT_H */