This file is indexed.

/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