/usr/include/TiledArray/perm_index.h is in libtiledarray-dev 0.6.0-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | /*
* This file is a part of TiledArray.
* Copyright (C) 2014 Virginia Tech
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Justus Calvin
* Department of Chemistry, Virginia Tech
*
* perm_index.h
* Oct 10, 2014
*
*/
#ifndef TILEDARRAY_PERM_INDEX_H__INCLUDED
#define TILEDARRAY_PERM_INDEX_H__INCLUDED
#include <TiledArray/range.h>
namespace TiledArray {
namespace detail {
/// A functor that permutes ordinal indices
/// The purpose of this functor is to allow fast, repeated permutations of
/// ordinal indices.
class PermIndex {
std::size_t* weights_; ///< A pointer that stores both the input and
///< output weights (or strides).
unsigned int ndim_; ///< The number of dimensions in the coordinate index space
public:
/// Default constructor
PermIndex() : weights_(NULL), ndim_(0) { }
/// Construct permuting functor
/// \param range The input range of ordinal indices
PermIndex(const Range& range, const Permutation& perm) :
weights_(NULL), ndim_(perm.dim())
{
if(ndim_ > 0) {
// Check the input data
TA_ASSERT(range.rank() == perm.dim());
// Construct the inverse permutation
const Permutation inv_perm_ = -perm;
// Allocate memory for this object
weights_ = static_cast<std::size_t*>(malloc((ndim_ + ndim_) * sizeof(std::size_t)));
if(! weights_)
throw std::bad_alloc();
// Construct restricted pointers to the input data
const auto* restrict const inv_perm = & inv_perm_.data().front();
const auto* restrict const range_size = range.extent_data();
const auto* restrict const range_weight = range.stride_data();
// Construct restricted pointers to the object data
std::size_t* restrict const input_weight = weights_;
std::size_t* restrict const output_weight = weights_ + ndim_;
// Initialize input and output weights
std::size_t volume = 1ul;
for(int i = int(ndim_) - 1; i >= 0; --i) {
// Load input data for iteration i.
const auto inv_perm_i = inv_perm[i];
const auto weight = range_weight[i];
const auto size = range_size[inv_perm_i];
// Store the input and output weights
output_weight[inv_perm_i] = volume;
volume *= size;
input_weight[i] = weight;
}
}
}
PermIndex(const PermIndex& other) :
weights_(NULL), ndim_(other.ndim_)
{
if(ndim_) {
// Allocate memory for this object
weights_ = static_cast<std::size_t*>(malloc((ndim_ + ndim_) * sizeof(std::size_t)));
if(! weights_)
throw std::bad_alloc();
// Copy data
memcpy(weights_, other.weights_, (ndim_ + ndim_) * sizeof(std::size_t));
}
}
~PermIndex() {
free(weights_);
weights_ = NULL;
}
PermIndex& operator=(const PermIndex& other) {
// Deallocate memory
if(ndim_ && (ndim_ != other.ndim_)) {
free(weights_);
weights_ = NULL;
}
const std::size_t bytes = (other.ndim_ + other.ndim_) * sizeof(std::size_t);
if(! weights_ && bytes) {
// Allocate new memory
weights_ = static_cast<std::size_t*>(malloc(bytes));
if(! weights_)
throw std::bad_alloc();
}
// copy the data (safe if ndim_ == 0)
ndim_ = other.ndim_;
memcpy(weights_, other.weights_, bytes);
return *this;
}
/// Dimension accessor
/// \return The dimension of the indices that can be permuted
int dim() const { return ndim_; }
/// Data accessor
/// \return A pointer to the result data
const std::size_t* data() const { return weights_; }
/// Compute the permuted index for the current block
std::size_t operator()(std::size_t index) const {
TA_ASSERT(ndim_);
TA_ASSERT(weights_);
// Construct restricted pointers to data
const std::size_t* restrict const input_weight = weights_;
const std::size_t* restrict const output_weight = weights_ + ndim_;
// create result index
std::size_t perm_index = 0ul;
for(unsigned int i = 0u; i < ndim_; ++i) {
const std::size_t input_weight_i = input_weight[i];
const std::size_t output_weight_i = output_weight[i];
perm_index += index / input_weight_i * output_weight_i;
index %= input_weight_i;
}
return perm_index;
}
// Check for valid permutation
operator bool() const { return ndim_; }
}; // class PermIndex
} // namespace detail
} // namespace TiledArray
#endif // MADNESS_PERM_INDEX_H__INCLUDED
TILEDARRAY_PERM_INDEX_H__INCLUDED
|