ROL
ROL_VectorWorkspace.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #pragma once
11 #ifndef ROL_VECTORWORKSPACE_HPP
12 #define ROL_VECTORWORKSPACE_HPP
13 
14 #include "ROL_Vector.hpp"
15 #include <iostream>
16 #include <map>
17 #include <utility>
18 
59 namespace ROL {
60 
61 namespace details {
62 
63 using namespace std;
64 
65 
66 template<typename Real>
68 
71 
72 private:
73 
74  struct VectorKey {
75  friend class VectorWorkspace<Real>;
76  size_t hash_code;
77  int dimension;
78 
79  VectorKey( const V& x ) :
80  hash_code(typeid(x).hash_code()),
81  dimension( x.dimension() ) {}
82 
83  VectorKey( const Ptr<V>& x ) :
84  VectorKey( *x ) {}
85 
86  static string to_string( const VectorKey& key ) {
87  stringstream ss;
88  ss << "VectorKey(" << hex << key.hash_code << ","
89  << dec << key.dimension << ")";
90  return ss.str();
91  }
92 
93  bool operator < ( const VectorKey& x ) const {
94  return ( hash_code < x.hash_code ) && ( dimension < x.dimension );
95  }
96 
97  bool operator == ( const VectorKey& x ) const {
98  return ( hash_code == x.hash_code ) && ( dimension == x.dimension );
99  }
100 
101 // bool operator != ( const VectorKey& x ) const {
102 // return ( hash_code != x.hash_code ) || ( dimension != x.dimension );
103 // }
104 
105  }; // class VectorKey
106 
107  struct VectorStack {
108 
109  friend class VectorWorkspace<Real>;
110  vector<Ptr<V>> vectors_;
112 
113  VectorStack( const V& x ) : vectors_( 1, x.clone() ),
114  key_(VectorKey(x)) {}
115 
116  const VectorKey& getKey() const { return key_; }
117 
118  size_type size() const { return vectors_.size(); }
119 
121  size_type count = 0;
122  for( auto v : vectors_ ) count += ( getCount(v) > 3 );
123  return count;
124  }
125 
129  Ptr<V> clone( const V& x ) {
130  VectorKey x_key(x);
131 
132  ROL_TEST_FOR_EXCEPTION( key_.hash_code != x_key.hash_code, logic_error,
133  "VectorWorkspace::VectorStack tried to clone a vector of type " <<
134  hex << key_.hash_code << ", but it can only clone vectors of type " <<
135  hex << x_key.hash_code );
136 
137  ROL_TEST_FOR_EXCEPTION( key_.dimension != x_key.dimension, logic_error,
138  "VectorWorkspace::VectorStack tried to clone a vector of dimension " <<
139  hex << key_.dimension << ", but it can only clone vectors of dimension " <<
140  hex << x_key.dimension );
141 
142  for( auto e : vectors_ ) { // Return first unreferenced vector
143  if( getCount(e) <= 2 ) { // Storing pointers in vector increments count
144  return e;
145  }
146  }
147  // If no unreferenced vectors exist, add a new one
148  auto v = x.clone();
149  vectors_.push_back( v );
150  return v;
151  }
152 
153  // For testing purposes
154  vector<size_type> getRefCounts( void ) const {
155  vector<size_type> counts;
156  for( auto e: vectors_ ) counts.push_back( getCount(e) );
157  return counts;
158  }
159 
160  }; // VectorStack
161 
162  map<VectorKey,Ptr<VectorStack>> workspace_;
163 
164 public:
165 
166  Ptr<V> clone( const V& x ) {
167 
168  VectorKey key(x);
169  size_type key_count{0};
170  Ptr<VectorStack> vstack{nullPtr};
171 
172  for( auto e : workspace_ ) key_count += (key == e.first);
173 
174  if( key_count == 0 ) { // New key
175  vstack = makePtr<VectorStack>(x);
176  workspace_.insert( make_pair(key,vstack) );
177  }
178  else vstack = workspace_[key];
179 
180  return vstack->clone(x);
181  }
182 
183  Ptr<V> clone( const Ptr<const V>& x ) { return clone(*x); }
184 
185  // Deep copy
186  Ptr<V> copy( const V& x ) {
187  auto xc = clone(x);
188  xc->set(x);
189  return xc;
190  }
191 
192  Ptr<V> copy( const Ptr<const V>& x ) { return copy(*x); }
193 
194  void status( ostream& os ) const {
195  os << "\n\n" << string(80,'-') << std::endl;
196  os << "VectorWorkspace contains the following VectorStack(hash_code,dim) entries:\n\n";
197  for( auto entry : workspace_ ) {
198  os << " VectorStack(" << hex << entry.first.hash_code << ","
199  << dec << entry.first.dimension << ")";
200  os << "\n Reference Counts per element" << std::endl;
201  for( auto e : entry.second->vectors_ ) {
202  os << " " << getCount( e ) << std::endl;
203  }
204  }
205  os << string(80,'-') << std::endl;
206  }
207 
208 
209 }; // VectorWorkspace
210 
211 } // namespace details
212 
214 
215 } // namespace ROL
216 
217 
218 #endif
typename vector< Real >::size_type size_type
typename PV< Real >::size_type size_type
VectorWorkspace< Real > workspace_
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
vector< size_type > getRefCounts(void) const
Ptr< V > copy(const Ptr< const V > &x)
static string to_string(const VectorKey &key)
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Provides a &quot;smart&quot; cloning manager to be used a member variable in a class and called in the member f...
Ptr< V > clone(const Ptr< const V > &x)
map< VectorKey, Ptr< VectorStack > > workspace_
void status(ostream &os) const