|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef COORDINATE_MAP_HPP |
|
|
#define COORDINATE_MAP_HPP |
|
|
|
|
|
#include "coordinate.hpp" |
|
|
#include "kernel_region.hpp" |
|
|
#include "types.hpp" |
|
|
|
|
|
#include <cmath> |
|
|
#include <functional> |
|
|
#include <iterator> |
|
|
#include <memory> |
|
|
#include <set> |
|
|
#include <tuple> |
|
|
#include <vector> |
|
|
|
|
|
#include <robin_hood.h> |
|
|
|
|
|
namespace minkowski { |
|
|
|
|
|
namespace detail { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename Itype> |
|
|
inline void |
|
|
stride_coordinate(const coordinate<Itype> &src, std::vector<Itype> &dst, |
|
|
const default_types::stride_type &stride) noexcept { |
|
|
dst[0] = src[0]; |
|
|
for (default_types::index_type i = 0; i < stride.size(); ++i) { |
|
|
dst[i + 1] = std::floor((float)src[i + 1] / stride[i]) * stride[i]; |
|
|
} |
|
|
} |
|
|
|
|
|
template <typename Itype, typename stride_type> |
|
|
inline void stride_coordinate(const coordinate<Itype> &src, |
|
|
std::vector<Itype> &dst, |
|
|
const stride_type stride) noexcept { |
|
|
dst[0] = src[0]; |
|
|
for (default_types::index_type i = 0; i < dst.size() - 1; ++i) { |
|
|
dst[i + 1] = std::floor((float)src[i + 1] / stride[i]) * stride[i]; |
|
|
} |
|
|
} |
|
|
|
|
|
inline default_types::stride_type |
|
|
stride_tensor_stride(const default_types::stride_type &tensor_stride, |
|
|
const default_types::stride_type &stride, |
|
|
bool is_transpose = false) { |
|
|
ASSERT(tensor_stride.size() == stride.size(), "stride size mismatch."); |
|
|
default_types::stride_type strided_tensor_stride{tensor_stride}; |
|
|
if (is_transpose) { |
|
|
for (default_types::size_type i = 0; i < tensor_stride.size(); ++i) { |
|
|
ASSERT(strided_tensor_stride[i] % stride[i] == 0, |
|
|
"Invalid up stride on tensor stride:", tensor_stride, |
|
|
"kernel stride:", stride); |
|
|
strided_tensor_stride[i] /= stride[i]; |
|
|
} |
|
|
} else { |
|
|
for (default_types::size_type i = 0; i < tensor_stride.size(); ++i) |
|
|
strided_tensor_stride[i] *= stride[i]; |
|
|
} |
|
|
return strided_tensor_stride; |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename coordinate_type, template <typename T> class TemplatedAllocator> |
|
|
class CoordinateMap { |
|
|
|
|
|
public: |
|
|
using self_type = CoordinateMap<coordinate_type, TemplatedAllocator>; |
|
|
using index_type = default_types::index_type; |
|
|
using size_type = default_types::size_type; |
|
|
using stride_type = default_types::stride_type; |
|
|
|
|
|
|
|
|
using index_vector_type = std::vector<default_types::index_type>; |
|
|
using index_set_type = std::set<default_types::index_type>; |
|
|
|
|
|
using byte_allocator_type = TemplatedAllocator<char>; |
|
|
|
|
|
|
|
|
|
|
|
CoordinateMap() = delete; |
|
|
CoordinateMap(size_type const number_of_coordinates, |
|
|
size_type const coordinate_size, |
|
|
stride_type const &stride = {1}, |
|
|
byte_allocator_type alloc = byte_allocator_type()) |
|
|
: m_coordinate_size(coordinate_size), |
|
|
m_capacity(0), |
|
|
m_tensor_stride(stride), m_byte_allocator(alloc) { |
|
|
allocate(number_of_coordinates); |
|
|
expand_tensor_stride(); |
|
|
LOG_DEBUG("tensor stride:", m_tensor_stride); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename key_iterator, typename mapped_iterator> |
|
|
void insert(key_iterator key_first, key_iterator key_last, |
|
|
mapped_iterator value_first, mapped_iterator value_last) { |
|
|
ASSERT(false, "Not implemented"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self_type stride(stride_type const &tensor_strides) const { |
|
|
ASSERT(false, "Not implemented"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
coordinate_type *coordinate_data() { return m_coordinates.get(); } |
|
|
coordinate_type const *const_coordinate_data() const { |
|
|
return m_coordinates.get(); |
|
|
} |
|
|
|
|
|
void reserve(size_type size) { |
|
|
if (m_capacity < size) { |
|
|
LOG_DEBUG("Reserve coordinates:", size, "current capacity:", m_capacity); |
|
|
allocate(size); |
|
|
} |
|
|
} |
|
|
|
|
|
std::string to_string() const; |
|
|
|
|
|
stride_type const &get_tensor_stride() const noexcept { |
|
|
return m_tensor_stride; |
|
|
} |
|
|
|
|
|
inline size_type capacity() const noexcept { return m_capacity; } |
|
|
|
|
|
inline size_type coordinate_size() const noexcept { |
|
|
return m_coordinate_size; |
|
|
} |
|
|
|
|
|
protected: |
|
|
|
|
|
void allocate(size_type const number_of_coordinates) { |
|
|
if (m_capacity < number_of_coordinates) { |
|
|
LOG_DEBUG("Allocate", number_of_coordinates, "coordinates."); |
|
|
auto const size = number_of_coordinates * m_coordinate_size; |
|
|
m_coordinates = allocate_ptr(size); |
|
|
m_capacity = number_of_coordinates; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::shared_ptr<coordinate_type[]> allocate_ptr(size_type const size) { |
|
|
coordinate_type *ptr = reinterpret_cast<coordinate_type *>( |
|
|
m_byte_allocator.allocate(size * sizeof(coordinate_type))); |
|
|
|
|
|
auto deleter = [](coordinate_type *p, byte_allocator_type alloc, |
|
|
size_type size) { |
|
|
alloc.deallocate(reinterpret_cast<char *>(p), size); |
|
|
}; |
|
|
|
|
|
return std::shared_ptr<coordinate_type[]>{ |
|
|
ptr, std::bind(deleter, std::placeholders::_1, m_byte_allocator, |
|
|
size * sizeof(coordinate_type))}; |
|
|
} |
|
|
|
|
|
private: |
|
|
|
|
|
|
|
|
|
|
|
void expand_tensor_stride() { |
|
|
if (m_tensor_stride.size() == 1) { |
|
|
for (size_type i = 0; i < m_coordinate_size - 2; ++i) { |
|
|
m_tensor_stride.push_back(m_tensor_stride[0]); |
|
|
} |
|
|
} |
|
|
ASSERT(m_tensor_stride.size() == m_coordinate_size - 1, |
|
|
"Invalid tensor stride", m_tensor_stride); |
|
|
} |
|
|
|
|
|
protected: |
|
|
|
|
|
size_type m_number_of_coordinates; |
|
|
size_type m_coordinate_size; |
|
|
size_type m_capacity; |
|
|
stride_type m_tensor_stride; |
|
|
|
|
|
byte_allocator_type m_byte_allocator; |
|
|
std::shared_ptr<coordinate_type[]> m_coordinates; |
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
#endif |
|
|
|