/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
 |