Teuchos_Workspace.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef TEUCHOS_WORKSPACE_HPP
00030 #define TEUCHOS_WORKSPACE_HPP
00031
00032 #include "Teuchos_RCP.hpp"
00033 #include "Teuchos_ArrayView.hpp"
00034 #include "Teuchos_TestForException.hpp"
00035
00036 namespace Teuchos {
00037
00038 class WorkspaceStore;
00039 class RawWorkspace;
00040
00052
00071 void set_default_workspace_store( const Teuchos::RCP<WorkspaceStore> &default_workspace_store );
00072
00075 Teuchos::RCP<WorkspaceStore> get_default_workspace_store();
00076
00084 void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out );
00085
00090 class RawWorkspace {
00091 public:
00093 friend class WorkspaceStore;
00116 RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes);
00118 ~RawWorkspace();
00120 size_t num_bytes() const;
00122 char* workspace_ptr();
00124 const char* workspace_ptr() const;
00125 private:
00126 WorkspaceStore *workspace_store_;
00127 char *workspace_begin_;
00128 char *workspace_end_;
00129 bool owns_memory_;
00130
00131
00132 RawWorkspace();
00133 RawWorkspace(const RawWorkspace&);
00134 RawWorkspace& operator=(const RawWorkspace&);
00135 static void* operator new(size_t);
00136 static void operator delete(void*);
00137 };
00138
00163 template<class T>
00164 class Workspace {
00165 public:
00197 Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true);
00201 ~Workspace();
00203 size_t size() const;
00206 T* getRawPtr();
00209 const T* getRawPtr() const;
00216 T& operator[](size_t i);
00223 const T& operator[](size_t i) const;
00225 operator ArrayView<T>();
00227 operator ArrayView<const T>() const;
00228 private:
00229 RawWorkspace raw_workspace_;
00230 bool call_constructors_;
00231
00232 Workspace();
00233 Workspace(const RawWorkspace&);
00234 Workspace& operator=(const RawWorkspace&);
00235 static void* operator new(size_t);
00236 static void operator delete(void*);
00237 };
00238
00250 class WorkspaceStore {
00251 public:
00253 friend class RawWorkspace;
00255 ~WorkspaceStore();
00258 size_t num_bytes_total() const;
00261 size_t num_bytes_remaining() const;
00267 int num_static_allocations() const;
00273 int num_dyn_allocations() const;
00277 size_t num_current_bytes_total();
00281 size_t num_max_bytes_needed() const;
00282 protected:
00284 WorkspaceStore(size_t num_bytes);
00286 void protected_initialize(size_t num_bytes);
00287 private:
00288 char *workspace_begin_;
00289
00290 char *workspace_end_;
00291
00292 char *curr_ws_ptr_;
00293
00294 int num_static_allocations_;
00295
00296 int num_dyn_allocations_;
00297
00298
00299 size_t num_current_bytes_total_;
00300 size_t num_max_bytes_needed_;
00301
00302 WorkspaceStore(const WorkspaceStore&);
00303 WorkspaceStore& operator=(const WorkspaceStore&);
00304 };
00305
00313 class WorkspaceStoreInitializeable
00314 : public WorkspaceStore
00315 {
00316 public:
00320 WorkspaceStoreInitializeable(size_t num_bytes = 0);
00327 void initialize(size_t num_bytes);
00328 };
00329
00331
00332
00333
00334
00335 template<class T>
00336 inline
00337 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors)
00338 : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors)
00339 {
00340 if(call_constructors_) {
00341 char* raw_ptr = raw_workspace_.workspace_ptr();
00342 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00343 ::new (raw_ptr) T();
00344 }
00345 }
00346
00347 template<class T>
00348 inline
00349 Workspace<T>::~Workspace()
00350 {
00351 if(call_constructors_) {
00352 const size_t num_elements = this->size();
00353 char* raw_ptr = raw_workspace_.workspace_ptr();
00354 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00355 reinterpret_cast<T*>(raw_ptr)->~T();
00356 }
00357 }
00358
00359 template<class T>
00360 inline
00361 size_t Workspace<T>::size() const
00362 {
00363 return raw_workspace_.num_bytes() / sizeof(T);
00364 }
00365
00366 template<class T>
00367 inline
00368 T* Workspace<T>::getRawPtr()
00369 {
00370 return ( size() ? &(*this)[0] : 0 );
00371 }
00372
00373 template<class T>
00374 inline
00375 const T* Workspace<T>::getRawPtr() const
00376 {
00377 return ( size() ? &(*this)[0] : 0 );
00378 }
00379
00380 template<class T>
00381 inline
00382 T& Workspace<T>::operator[](size_t i)
00383 {
00384 #ifdef TEUCHOS_DEBUG
00385 TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" );
00386 #endif
00387 return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i];
00388 }
00389
00390 template<class T>
00391 inline
00392 const T& Workspace<T>::operator[](size_t i) const
00393 {
00394 return const_cast<Workspace<T>*>(this)->operator[](i);
00395 }
00396
00397 template<class T>
00398 inline
00399 Workspace<T>::operator ArrayView<T>()
00400 {
00401 if (size()==0)
00402 return Teuchos::null;
00403 return arrayView<T>( &(*this)[0], size() );
00404 }
00405
00406 template<class T>
00407 inline
00408 Workspace<T>::operator ArrayView<const T>() const
00409 {
00410 if (size()==0)
00411 return Teuchos::null;
00412 return arrayView<const T>( &(*this)[0], size() );
00413 }
00414
00415 #ifdef __PGI // Should not have to define this but pgCC is complaining!
00416 template<class T>
00417 inline
00418 void* Workspace<T>::operator new(size_t)
00419 {
00420 assert(0);
00421 return NULL;
00422 }
00423 #endif
00424
00425
00426 template<class T>
00427 inline
00428 void Workspace<T>::operator delete(void*)
00429 {
00430 assert(0);
00431 }
00432
00433
00434
00435
00436 inline
00437 size_t WorkspaceStore::num_bytes_total() const
00438 {
00439 return workspace_end_ - workspace_begin_;
00440 }
00441
00442 inline
00443 size_t WorkspaceStore::num_bytes_remaining() const
00444 {
00445 return workspace_end_ - curr_ws_ptr_;
00446 }
00447
00448 inline
00449 int WorkspaceStore::num_static_allocations() const
00450 {
00451 return num_static_allocations_;
00452 }
00453
00454 inline
00455 int WorkspaceStore::num_dyn_allocations() const
00456 {
00457 return num_dyn_allocations_;
00458 }
00459
00460 inline
00461 size_t WorkspaceStore::num_current_bytes_total()
00462 {
00463 return num_current_bytes_total_;
00464 }
00465
00466 inline
00467 size_t WorkspaceStore::num_max_bytes_needed() const
00468 {
00469 return num_max_bytes_needed_;
00470 }
00471
00472
00473
00474
00475 inline
00476 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes)
00477 : WorkspaceStore(num_bytes)
00478 {}
00479
00480 inline
00481 void WorkspaceStoreInitializeable::initialize(size_t num_bytes)
00482 {
00483 protected_initialize(num_bytes);
00484 }
00485
00486
00487
00488
00489 inline
00490 size_t RawWorkspace::num_bytes() const
00491 {
00492 return workspace_end_ - workspace_begin_;
00493 }
00494
00495 inline
00496 char* RawWorkspace::workspace_ptr()
00497 {
00498 return workspace_begin_;
00499 }
00500
00501 inline
00502 const char* RawWorkspace::workspace_ptr() const
00503 {
00504 return workspace_begin_;
00505 }
00506
00507
00508 inline
00509 void RawWorkspace::operator delete(void*)
00510 {
00511 assert(0);
00512 }
00513
00514 }
00515
00516 #endif // TEUCHOS_WORKSPACE_HPP