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 template<typename Real>
65 
68 
69 private:
70 
71  struct VectorKey {
72  friend class VectorWorkspace<Real>;
73  size_t hash_code;
74  int dimension;
75 
76  VectorKey( const V& x ) :
77  hash_code(typeid(x).hash_code()),
78  dimension( x.dimension() ) {}
79 
80  VectorKey( const Ptr<V>& x ) :
81  VectorKey( *x ) {}
82 
83  static std::string to_string( const VectorKey& key ) {
84  std::stringstream ss;
85  ss << "VectorKey(" << std::hex << key.hash_code << ","
86  << std::dec << key.dimension << ")";
87  return ss.str();
88  }
89 
90  bool operator < ( const VectorKey& x ) const {
91  return ( hash_code < x.hash_code ) && ( dimension < x.dimension );
92  }
93 
94  bool operator == ( const VectorKey& x ) const {
95  return ( hash_code == x.hash_code ) && ( dimension == x.dimension );
96  }
97 
98 // bool operator != ( const VectorKey& x ) const {
99 // return ( hash_code != x.hash_code ) || ( dimension != x.dimension );
100 // }
101 
102  }; // class VectorKey
103 
104  struct VectorStack {
105 
106  friend class VectorWorkspace<Real>;
107  std::vector<Ptr<V>> vectors_;
109 
110  VectorStack( const V& x ) : vectors_( 1, x.clone() ),
111  key_(VectorKey(x)) {}
112 
113  const VectorKey& getKey() const { return key_; }
114 
115  size_type size() const { return vectors_.size(); }
116 
118  size_type count = 0;
119  for( auto v : vectors_ ) count += ( getCount(v) > 3 );
120  return count;
121  }
122 
126  Ptr<V> clone( const V& x ) {
127  VectorKey x_key(x);
128 
129  ROL_TEST_FOR_EXCEPTION( key_.hash_code != x_key.hash_code, std::logic_error,
130  "VectorWorkspace::VectorStack tried to clone a std::vector of type " <<
131  std::hex << key_.hash_code << ", but it can only clone std::vectors of type " <<
132  std::hex << x_key.hash_code );
133 
134  ROL_TEST_FOR_EXCEPTION( key_.dimension != x_key.dimension, std::logic_error,
135  "VectorWorkspace::VectorStack tried to clone a std::vector of dimension " <<
136  std::hex << key_.dimension << ", but it can only clone std::vectors of dimension " <<
137  std::hex << x_key.dimension );
138 
139  for( auto e : vectors_ ) { // Return first unreferenced std::vector
140  if( getCount(e) <= 2 ) { // Storing pointers in std::vector increments count
141  return e;
142  }
143  }
144  // If no unreferenced std::vectors exist, add a new one
145  auto v = x.clone();
146  vectors_.push_back( v );
147  return v;
148  }
149 
150  // For testing purposes
151  std::vector<size_type> getRefCounts( void ) const {
152  std::vector<size_type> counts;
153  for( auto e: vectors_ ) counts.push_back( getCount(e) );
154  return counts;
155  }
156 
157  }; // VectorStack
158 
159  std::map<VectorKey,Ptr<VectorStack>> workspace_;
160 
161 public:
162 
163  Ptr<V> clone( const V& x ) {
164 
165  VectorKey key(x);
166  size_type key_count{0};
167  Ptr<VectorStack> vstack{nullPtr};
168 
169  for( auto e : workspace_ ) key_count += (key == e.first);
170 
171  if( key_count == 0 ) { // New key
172  vstack = makePtr<VectorStack>(x);
173  workspace_.insert( std::make_pair(key,vstack) );
174  }
175  else vstack = workspace_[key];
176 
177  return vstack->clone(x);
178  }
179 
180  Ptr<V> clone( const Ptr<const V>& x ) { return clone(*x); }
181 
182  // Deep copy
183  Ptr<V> copy( const V& x ) {
184  auto xc = clone(x);
185  xc->set(x);
186  return xc;
187  }
188 
189  Ptr<V> copy( const Ptr<const V>& x ) { return copy(*x); }
190 
191  void status( std::ostream& os ) const {
192  os << "\n\n" << std::string(80,'-') << std::endl;
193  os << "VectorWorkspace contains the following VectorStack(hash_code,dim) entries:\n\n";
194  for( auto entry : workspace_ ) {
195  os << " VectorStack(" << std::hex << entry.first.hash_code << ","
196  << std::dec << entry.first.dimension << ")";
197  os << "\n Reference Counts per element" << std::endl;
198  for( auto e : entry.second->vectors_ ) {
199  os << " " << getCount( e ) << std::endl;
200  }
201  }
202  os << std::string(80,'-') << std::endl;
203  }
204 
205 
206 }; // VectorWorkspace
207 
208 } // namespace details
209 
211 
212 } // namespace ROL
213 
214 
215 #endif
typename PV< Real >::size_type size_type
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
bool operator==(const VectorKey &x) const
Ptr< V > copy(const Ptr< const V > &x)
void status(std::ostream &os) const
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...
std::map< VectorKey, Ptr< VectorStack > > workspace_
Ptr< V > clone(const Ptr< const V > &x)
typename std::vector< Real >::size_type size_type
std::vector< size_type > getRefCounts(void) const
bool operator<(const VectorKey &x) const
static std::string to_string(const VectorKey &key)