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
59namespace ROL {
60
61namespace details {
62
63template<typename Real>
65
67 using size_type = typename std::vector<Real>::size_type;
68
69private:
70
71 struct VectorKey {
72 friend class VectorWorkspace<Real>;
73 size_t hash_code;
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
161public:
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
Defines the linear algebra or vector space interface.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
Ptr< V > copy(const Ptr< const V > &x)
typename std::vector< Real >::size_type size_type
void status(std::ostream &os) const
Ptr< V > clone(const Ptr< const V > &x)
std::map< VectorKey, Ptr< VectorStack > > workspace_
bool operator==(const VectorKey &x) const
static std::string to_string(const VectorKey &key)
std::vector< size_type > getRefCounts(void) const