This file is indexed.

/usr/include/TiledArray/distributed_storage.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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*
 *  This file is a part of TiledArray.
 *  Copyright (C) 2013  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/>.
 *
 */

#ifndef TILEDARRAY_DISTRIBUTED_STORAGE_H__INCLUDED
#define TILEDARRAY_DISTRIBUTED_STORAGE_H__INCLUDED

#include <TiledArray/pmap/pmap.h>

namespace TiledArray {
  namespace detail {

    /// Distributed storage container.

    /// Each element in this container is owned by a single node, but any node
    /// may request a copy of the element in the form of a \c Future .
    /// The owner of each element is defined by a process map (pmap), which is
    /// passed to the constructor. Elements do not need to be explicitly
    /// initialized because they will be added to the container when the element
    /// is first accessed, though you may manually initialize an element with
    /// the \c insert() function. All elements are stored in \c Future ,
    /// which may be set only once.
    /// \note This object is derived from \c WorldObject , which means
    /// the order of construction of object must be the same on all nodes. This
    /// can easily be achieved by only constructing world objects in the main
    /// thread. DO NOT construct world objects within tasks where the order of
    /// execution is nondeterministic.
    template <typename T>
    class DistributedStorage : public madness::WorldObject<DistributedStorage<T> > {
    public:
      typedef DistributedStorage<T> DistributedStorage_; ///< This object type
      typedef madness::WorldObject<DistributedStorage_> WorldObject_; ///< Base object type

      typedef std::size_t size_type; ///< size type
      typedef size_type key_type; ///< element key type
      typedef T value_type; ///< Element type
      typedef Future<value_type> future; ///< Element container type
      typedef Pmap pmap_interface; ///< Process map interface type
      typedef madness::ConcurrentHashMap<key_type, future> container_type; ///< Local container type
      typedef typename container_type::accessor accessor; ///< Local element accessor type
      typedef typename container_type::const_accessor const_accessor; ///< Local element const accessor type

    private:

      const size_type max_size_; ///< The maximum number of elements that can be stored by this container
      std::shared_ptr<pmap_interface> pmap_; ///< The process map that defines the element distribution
      mutable container_type data_; ///< The local data container

      // not allowed
      DistributedStorage(const DistributedStorage_&);
      DistributedStorage_& operator=(const DistributedStorage_&);

      future get_local(const size_type i) const {
        TA_ASSERT(pmap_->is_local(i));

        // Return the local element.
        const_accessor acc;
        data_.insert(acc, i);
        return acc->second;
      }

      void set_handler(const size_type i, const value_type& value) {
        future f = get_local(i);

#ifndef NDEBUG
          // Check that the future has not been set already.
          if(f.probe())
            TA_EXCEPTION("Tile has already been assigned.");
#endif // NDEBUG

        f.set(value);
      }

      void get_handler(const size_type i, const typename future::remote_refT& ref) {
        future f = get_local(i);
        future remote_f(ref);
        remote_f.set(f);
      }

      void set_remote(const size_type i, const value_type& value) {
        WorldObject_::task(owner(i), & DistributedStorage_::set_handler,
            i, value, madness::TaskAttributes::hipri());
      }

      struct DelayedSet : public madness::CallbackInterface {
      private:
        DistributedStorage_& ds_; ///< A reference to the owning object
        size_type index_; ///< The index that will own the future
        future future_; ///< The future that we are waiting on.

      public:

        DelayedSet(DistributedStorage_& ds, size_type i, const future& f) :
            ds_(ds), index_(i), future_(f)
        { }

        virtual ~DelayedSet() { }

        virtual void notify() {
          ds_.set_remote(index_, future_);
          delete this;
        }
      }; // struct DelayedSet

    public:

      /// Makes an initialized, empty container with default data distribution (no communication)

      /// A unique ID is associated with every distributed container within a
      /// world.  In order to avoid synchronization when making a container, we
      /// have to assume that all processes execute this constructor in the same
      /// order (does not apply to the non-initializing, default constructor).
      /// \param world The world where the distributed container lives
      /// \param max_size The maximum capacity of this container
      /// \param pmap The process map for the container (default = null pointer)
      DistributedStorage(World& world, size_type max_size,
          const std::shared_ptr<pmap_interface>& pmap) :
        WorldObject_(world), max_size_(max_size),
        pmap_(pmap),
        data_((max_size / world.size()) + 11)
      {
        // Check that the process map is appropriate for this storage object
        TA_ASSERT(pmap_);
        TA_ASSERT(pmap_->size() == max_size);
        TA_ASSERT(pmap_->rank() == pmap_interface::size_type(world.rank()));
        TA_ASSERT(pmap_->procs() == pmap_interface::size_type(world.size()));
        WorldObject_::process_pending();
      }

      virtual ~DistributedStorage() { }

      using WorldObject_::get_world;

      /// Process map accessor

      /// \return A shared pointer to the process map.
      /// \throw nothing
      const std::shared_ptr<pmap_interface>& pmap() const { return pmap_; }

      /// Element owner

      /// \return The process that owns element \c i
      ProcessID owner(size_type i) const {
        TA_ASSERT(i < max_size_);
        TA_ASSERT(pmap_);
        return pmap_->owner(i);
      }

      /// Local element query

      /// Check if element \c i belongs to this node. The element may or may not
      /// be stored. Use \c find to determine if an element is present.
      /// \param i The element to check.
      /// \return \c true when the element is stored locally, otherwise \c false.
      bool is_local(size_type i) const {
        TA_ASSERT(i < max_size_);
        TA_ASSERT(pmap_);
        return pmap_->is_local(i);
      }

      /// Number of local elements

      /// No communication.
      /// \return The number of local elements stored by the container.
      /// \throw nothing
      size_type size() const { return data_.size(); }

      /// Max size accessor

      /// The maximum size is the total number of elements that can be held by
      /// this container on all nodes, not on each node.
      /// \return The maximum number of elements.
      /// \throw nothing
      size_type max_size() const { return max_size_; }

      /// Get local or remote node

      /// \param i The element to get
      /// \return A future to element \c i
      /// \throw TiledArray::Exception If \c i is greater than or equal to \c max_size() .
      future get(size_type i) const {
        TA_ASSERT(i < max_size_);
        if(is_local(i)) {
          return get_local(i);
        } else {
          // Send a request to the owner of i for the element.
          future result;
          WorldObject_::task(owner(i), & DistributedStorage_::get_handler, i,
              result.remote_ref(get_world()), madness::TaskAttributes::hipri());

          return result;
        }
      }

      /// Set element \c i with \c value

      /// \param i The element to be set
      /// \param value The value of element \c i
      /// \throw TiledArray::Exception If \c i is greater than or equal to \c max_size() .
      /// \throw madness::MadnessException If \c i has already been set.
      void set(size_type i, const value_type& value) {
        TA_ASSERT(i < max_size_);
        if(is_local(i))
          set_handler(i, value);
        else
          set_remote(i, value);
      }

      /// Set element \c i with a \c Future \c f

      /// The owner of \c i may be local or remote. If \c i is remote, a task
      /// is spawned on the owning node after the local future has been assigned.
      /// If \c i is not already in the container, it will be inserted.
      /// \param i The element to be set
      /// \param f The future for element \c i
      /// \throw madness::MadnessException If \c i has already been set.
      /// \throw TiledArray::Exception If \c i is greater than or equal to \c max_size() .
      void set(size_type i, const future& f) {
        TA_ASSERT(i < max_size_);
        if(is_local(i)) {
          const_accessor acc;
          if(! data_.insert(acc, typename container_type::datumT(i, f))) {
            // The element was already in the container, so set it with f.
            future existing_f = acc->second;
            acc.release();

            // Check that the future has not been set already.
#ifndef NDEBUG
            if(existing_f.probe())
              TA_EXCEPTION("Tile has already been assigned.");
#endif // NDEBUG
            // Set the future
            existing_f.set(f);
          }
        } else {
          if(f.probe()) {
            set_remote(i, f);
          } else {
            DelayedSet* set_callback = new DelayedSet(*this, i, f);
            const_cast<future&>(f).register_callback(set_callback);
          }
        }
      }

    }; // class DistributedStorage

  }  // namespace detail
}  // namespace TiledArray

#endif // TILEDARRAY_DISTRIBUTED_STORAGE_H__INCLUDED