File: DependencyManager.h

package info (click to toggle)
lammps 20220106.git7586adbb6a%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 348,064 kB
  • sloc: cpp: 831,421; python: 24,896; xml: 14,949; f90: 10,845; ansic: 7,967; sh: 4,226; perl: 4,064; fortran: 2,424; makefile: 1,501; objc: 238; lisp: 163; csh: 16; awk: 14; tcl: 6
file content (326 lines) | stat: -rw-r--r-- 11,301 bytes parent folder | download | duplicates (2)
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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
// A class for wrapping matrix operations with dependency information to speed up execution

#ifndef DEPENDENCY_MANAGER_H
#define DEPENDENCY_MANAGER_H

#include "ATC_TypeDefs.h"
#include "MatrixLibrary.h"
#include "ATC_Error.h"
#include "MPI_Wrappers.h"

namespace ATC {

  class InterscaleManager;

  /** memory type */
  enum MemoryType
  {
    TEMPORARY = 0,
    PERSISTENT
  };

  /**
   *  @class  DependencyManager
   *  @brief  Base class for defining objects that manage the dependencies of various objects
   */

  class DependencyManager {

  public:

    // used as a friend so it can perform a depth-first search to have safe deletions of managed dependencies
    friend class InterscaleManager;

    // constructor
    DependencyManager() : needReset_(true), isFixed_(false), memoryType_(TEMPORARY), dfsFound_(false) {};

    // destructor
    virtual ~DependencyManager() {};

    /** registration by other PerAtomQuantity objects */
    void register_dependence(DependencyManager * dependentQuantity)
    {dependentQuantities_.insert(dependentQuantity);};

    /** removes dependencies from the set */
    void remove_dependence(DependencyManager * dependentQuantity)
    {dependentQuantities_.erase(dependentQuantity);};

    /** check if a reset is required */
    bool need_reset() const {return needReset_ && !isFixed_;};

    /** propagate need to reset to to dependencies */
    void propagate_reset()
    {
      if (!isFixed_) {
        std::set<DependencyManager *>::iterator it;
        for (it = dependentQuantities_.begin(); it != dependentQuantities_.end(); it++)
          (*it)->force_reset();
      }
    };

    /** actions associated with indicating this quantity requires a reset */
    void set_reset()
    {
      needReset_ = true;
    }

    /** flip this object to needing a reset, and get dependencies */
    void force_reset()
    {
      set_reset();
      propagate_reset();
    }

    /** force quantity to be held fixed, enables dependent quantity to be used as persistent storage */
    void fix_quantity() {isFixed_ = true;};

    /** unfix the quantity */
    void unfix_quantity()
    {
      if (isFixed_) {
        isFixed_ = false;
        if (needReset_) propagate_reset();
      }
    };

    /** check on the memory type of the quantity */
    MemoryType memory_type() const {return memoryType_;};

    /** set the memory type of the quantity */
    void set_memory_type(MemoryType memoryType) {memoryType_ = memoryType;};


  protected:

    /** list of dependent atomic quantities */
    std::set<DependencyManager * > dependentQuantities_;

    /** flag for needing a recent */
    // mutable is applied because there can be internal updates because we update when needed rather than when pushed
    mutable bool needReset_;

    /** flag for if quantity is being held fixed */
    bool isFixed_;

    /** flag for if the quantity is temporary (per-run) */
    MemoryType memoryType_;

    /** flag for if the node has been found in depth-first search */
    bool dfsFound_;

  };

  /**
   *  @class  MatrixDependencyManager
   *  @brief  Class for defining objects that manage the dependencies of matrices
   */

  // Matrix class T, underlying type U
  template <template <typename> class T, typename U>
  class MatrixDependencyManager : public DependencyManager {

  public:

    MatrixDependencyManager() {};
    MatrixDependencyManager(int nRows, int nCols) : quantity_(nRows,nCols) {};
    virtual ~MatrixDependencyManager() {};

    /** returns a non-const version for manipulations and changes, resets dependent quantities */
    virtual T<U> & set_quantity() {propagate_reset(); return get_quantity();};

    /** access to a constant dense matrix of the quantity, indexed by AtC atom counts */
    virtual const T<U> & quantity() const {return get_quantity();};

    /** number of rows in quantity */
    virtual int nRows() const {return (this->quantity()).nRows();};

    /** number of columns in quantity */
    virtual int nCols() const {return (this->quantity()).nCols();};

    /** size of the matrix */
    virtual int size() const {return (this->quantity()).size();};

    /** reset the quantities size */
    void reset(INDEX nRows, INDEX nCols) {get_quantity().reset(nRows,nCols); propagate_reset();};

    /** resize the quantities size */
    void resize(INDEX nRows, INDEX nCols) {get_quantity().resize(nRows,nCols); propagate_reset();};

    /** sets the quantity to a given value */
    virtual void operator=(const T<U> & target) {get_quantity()=target; propagate_reset();};
    /** sets the quantity to a given constant value */
    virtual void operator=(U target) {get_quantity()=target; propagate_reset();};

    /** adds the given data to the Lammps quantity */
    virtual void operator+=(const T<U> & addition) {get_quantity()+=addition; propagate_reset();};
    /** adds the scalar data to the Lammps quantity for AtC atoms */
    virtual void operator+=(U addition) {get_quantity()+=addition; propagate_reset();};

    /** adds the given data to the Lammps quantity */
    virtual void operator-=(const T<U> & subtraction) {get_quantity()-=subtraction; propagate_reset();};
    /** adds the scalar data to the Lammps quantity for AtC atoms */
    virtual void operator-=(U subtraction) {get_quantity()-=subtraction; propagate_reset();};

    /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
    virtual void operator*=(const T<U> & multiplier) {get_quantity()*=multiplier; propagate_reset();};
    /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
    virtual void operator*=(U multiplier) {get_quantity()*=multiplier; propagate_reset();};

    /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
    virtual void operator/=(const T<U> & divisor) {get_quantity()/=divisor; propagate_reset();};
    /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
    virtual void operator/=(U divisor) {get_quantity()/=divisor; propagate_reset();};

    // I have no idea why these won't compile (JAT, 04/07/11)
    /** adds the given data to the Lammps quantity */
    virtual void operator+=(const MatrixDependencyManager<T,U> & addition) {get_quantity()+=addition.quantity(); propagate_reset();};

    /** adds the given data to the Lammps quantity */
    virtual void operator-=(const MatrixDependencyManager<T,U> & subtraction) {get_quantity()-=subtraction.quantity(); propagate_reset();};

    /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
    virtual void operator*=(const MatrixDependencyManager<T,U> & multiplier) {get_quantity()*=multiplier.quantity(); propagate_reset();};

    /** multiples the Lammps quantity by the given data, input is indexed in AtC atom counts */
    virtual void operator/=(const MatrixDependencyManager<T,U> & divisor) {get_quantity()/=divisor.quantity(); propagate_reset();};

    /** execute the matrix print command */
    virtual void print(const std::string &name) const {get_quantity().print(name);};

  protected:

    // This getter can be overridden by derived classes if they need e.g. a
    // differently-constructed quantity, but would like to use the same operators.
    virtual T<U> &get_quantity() const { return quantity_; }

    /** matrix */
    // mutable is applied because there can be internal updates because we update when needed rather than when pushed
    mutable T<U> quantity_;

  };


  /**
   *  @class MatrixDependencyManager<ParSparseMatrix, T>
   *  @brief Class for defining objects that manage the dependencies of parallelized sparse matrices
   */
  template<typename T>
  class MatrixDependencyManager<ParSparseMatrix, T> :
    public MatrixDependencyManager<SparseMatrix, T>
  {
  public:

    MatrixDependencyManager(MPI_Comm comm) :
      MatrixDependencyManager<SparseMatrix, T>(), quantity_(comm) {};

    MatrixDependencyManager(MPI_Comm comm, int nRows, int nCols) :
      MatrixDependencyManager<SparseMatrix, T>(), quantity_(comm, nRows, nCols) {};

    virtual ~MatrixDependencyManager() {};

  protected:

    // Let the superclass's operators work on our ParSparseMatrix.
    virtual ParSparseMatrix<T> &get_quantity() const { return quantity_; }

    mutable ParSparseMatrix<T> quantity_;

  };


  /**
   *  @class MatrixDependencyManager<ParDiagonalMatrix, T>
   *  @brief Class for defining objects that manage the dependencies of parallelized diagonal matrices
   */
  template<typename T>
  class MatrixDependencyManager<ParDiagonalMatrix, T> :
    public MatrixDependencyManager<DiagonalMatrix, T>
  {
  public:

    MatrixDependencyManager(MPI_Comm comm) :
      MatrixDependencyManager<DiagonalMatrix, T>(), quantity_(comm) {};

    MatrixDependencyManager(MPI_Comm comm, int nRows, int nCols) :
      MatrixDependencyManager<DiagonalMatrix, T>(), quantity_(comm, nRows, nCols) {};

    virtual ~MatrixDependencyManager() {};

  protected:

    // Let the superclass's operators work on our ParDiagonalMatrix.
    virtual ParDiagonalMatrix<T> &get_quantity() const { return quantity_; }

    mutable ParDiagonalMatrix<T> quantity_;

  };

  /**
   *  @class  SetDependencyManager
   *  @brief  Class for defining objects that manage the dependencies of standard library sets
   */
  template <typename T>
  class SetDependencyManager : public DependencyManager {

  public:

    // constructor
    SetDependencyManager() :
      DependencyManager(), quantity_() {};

    // destructor
    virtual ~SetDependencyManager() {};

    /** returns a non-const version for manipulations and changes, resets dependent quantities */
    virtual std::set<T> & set_quantity() {propagate_reset(); return quantity_;};

    /** access to a constant dense matrix of the quantity, indexed by AtC atom counts */
    virtual const std::set<T> & quantity() const {return quantity_;};

    /** size of the set */
    virtual int size() const {return (this->quantity()).size();};

  protected:

    /** underlying set */
    // mutable is applied because there can be internal updates because we update when needed rather than when pushed
    mutable std::set<T> quantity_;

  };

  /**
   *  @class  VectorDependencyManager
   *  @brief  Class for defining objects that manage the dependencies of standard library vectors
   */
  template <typename T>
  class VectorDependencyManager : public DependencyManager {

  public:

    // constructor
    VectorDependencyManager() :
      DependencyManager(), quantity_() {};

    // destructor
    virtual ~VectorDependencyManager() {};

    /** returns a non-const version for manipulations and changes, resets dependent quantities */
    virtual std::vector<T> & set_quantity() {propagate_reset(); return quantity_;};

    /** access to a constant dense matrix of the quantity, indexed by AtC atom counts */
    virtual const std::vector<T> & quantity() const {return quantity_;};

    /** size of the set */
    virtual int size() const {return (this->quantity()).size();};

  protected:

    /** underlying set */
    // mutable is applied because there can be internal updates because we update when needed rather than when pushed
    mutable std::vector<T> quantity_;

  };

}

#endif