Teuchos_Workspace.hpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #ifndef TEUCHOS_WORKSPACE_HPP
00030 #define TEUCHOS_WORKSPACE_HPP
00031 
00032 #include "Teuchos_RefCountPtr.hpp"
00033 #include "Teuchos_TestForException.hpp"
00034 
00035 namespace Teuchos {
00036 
00037 class WorkspaceStore;
00038 class RawWorkspace;
00039 
00041 
00050 
00052 
00070 void set_default_workspace_store( const Teuchos::RefCountPtr<WorkspaceStore> &default_workspace_store );
00071 
00073 
00075 Teuchos::RefCountPtr<WorkspaceStore> get_default_workspace_store();
00076 
00078 
00085 void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out );
00086 
00088 
00092 class RawWorkspace {
00093 public:
00095   friend class WorkspaceStore;
00097 
00119   RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes);
00121   ~RawWorkspace();
00123   size_t num_bytes() const;
00125   char* workspace_ptr();
00127   const char* workspace_ptr() const;
00128 private:
00129   WorkspaceStore   *workspace_store_;
00130   char             *workspace_begin_;
00131   char             *workspace_end_;
00132   bool             owns_memory_;  // If true then the pointed to memory was allocated with
00133                                   // new so we need to call delete on it when we are destroyed.
00134   // not defined and not to be called
00135   RawWorkspace();
00136   RawWorkspace(const RawWorkspace&);
00137   RawWorkspace& operator=(const RawWorkspace&);
00138   static void* operator new(size_t);
00139   static void operator delete(void*);
00140 }; // end class RawWorkspace
00141 
00143 
00167 template<class T>
00168 class Workspace {
00169 public:
00171 
00202   Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true);
00204 
00207   ~Workspace();
00209   size_t size() const;
00211 
00217   T& operator[](size_t i);
00219 
00225   const T& operator[](size_t i) const;
00226 private:
00227   RawWorkspace  raw_workspace_;
00228   bool          call_constructors_;
00229   // not defined and not to be called
00230   Workspace();
00231   Workspace(const RawWorkspace&);
00232   Workspace& operator=(const RawWorkspace&);
00233   static void* operator new(size_t);
00234   static void operator delete(void*);
00235 }; // end class Workspace
00236 
00238 
00249 class WorkspaceStore {
00250 public:
00252   friend class RawWorkspace;
00254   ~WorkspaceStore();
00256 
00258   size_t num_bytes_total() const;
00260 
00262   size_t num_bytes_remaining() const;
00264 
00269   int num_static_allocations() const;
00271 
00276   int num_dyn_allocations() const;
00278 
00281   size_t num_current_bytes_total();
00283 
00286   size_t num_max_bytes_needed() const;
00287 protected:
00289   WorkspaceStore(size_t num_bytes);
00291   void protected_initialize(size_t num_bytes);
00292 private:
00293   char    *workspace_begin_; // Points to the beginning of raw allocated workspace.
00294                              // If NULL then no workspace has been allocated yet.
00295   char    *workspace_end_;   // Points to one past the last byte of allocated workspace.
00296                              // workspace_end_ >= workspace_begin_
00297   char    *curr_ws_ptr_;     // Points to the first available byte of workspace.
00298                              // workspace_begin_ <= curr_ws_ptr_ <= workspace_end_
00299   int     num_static_allocations_; // Number of workspace allocation using already
00300                              // allocated memory.
00301   int     num_dyn_allocations_; // Number of workspace allocations using dynamic
00302                              // memory because the current workspace store was
00303                              // overridden
00304   size_t  num_current_bytes_total_; // Total bytes currently being used
00305   size_t  num_max_bytes_needed_; // Maximum number of bytes of storage needed
00306   // Not definted and not to be called
00307   WorkspaceStore(const WorkspaceStore&);
00308   WorkspaceStore& operator=(const WorkspaceStore&);
00309 }; // end class WorkspaceStore
00310 
00312 
00319 class WorkspaceStoreInitializeable
00320   : public WorkspaceStore
00321 {
00322 public:
00324 
00327   WorkspaceStoreInitializeable(size_t num_bytes = 0);
00329 
00335   void initialize(size_t num_bytes);
00336 }; // end class WorkspaceStoreInitializeable
00337 
00339 
00340 // /////////////////////////////////////
00341 // Inline members for Workspace<T>
00342 
00343 template<class T>
00344 inline
00345 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors)
00346   : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors)
00347 {
00348   if(call_constructors_) {
00349     char* raw_ptr = raw_workspace_.workspace_ptr();
00350     for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00351       ::new (raw_ptr) T(); // placement new
00352   }
00353 }
00354 
00355 template<class T>
00356 inline
00357 Workspace<T>::~Workspace()
00358 {
00359   if(call_constructors_) {
00360     const size_t num_elements = this->size();
00361     char* raw_ptr = raw_workspace_.workspace_ptr();
00362     for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00363       reinterpret_cast<T*>(raw_ptr)->~T();
00364   }
00365 }
00366 
00367 template<class T>
00368 inline
00369 size_t Workspace<T>::size() const
00370 {
00371   return raw_workspace_.num_bytes() / sizeof(T);
00372 }
00373 
00374 template<class T>
00375 inline
00376 T& Workspace<T>::operator[](size_t i)
00377 {
00378 #ifdef _DEBUG
00379   TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" );
00380 #endif  
00381   return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i];
00382 }
00383 
00384 template<class T>
00385 inline
00386 const T& Workspace<T>::operator[](size_t i) const
00387 {
00388   return const_cast<Workspace<T>*>(this)->operator[](i);
00389 }
00390 
00391 #ifdef __PGI // Should not have to define this but pgCC is complaining!
00392 template<class T>
00393 inline
00394 void* Workspace<T>::operator new(size_t)
00395 {
00396   assert(0);
00397   return NULL;
00398 }
00399 #endif
00400 
00401 // should not have to define this but the gcc-2.95.2 compiler is complaining!
00402 template<class T>
00403 inline
00404 void Workspace<T>::operator delete(void*)
00405 {
00406   assert(0);
00407 }
00408 
00409 // /////////////////////////////////////
00410 // Inline members for WorkspaceStore
00411 
00412 inline
00413 size_t WorkspaceStore::num_bytes_total() const
00414 {
00415   return workspace_end_ - workspace_begin_;
00416 }
00417 
00418 inline
00419 size_t WorkspaceStore::num_bytes_remaining() const
00420 {
00421   return workspace_end_ - curr_ws_ptr_;
00422 }
00423 
00424 inline
00425 int WorkspaceStore::num_static_allocations() const
00426 {
00427   return num_static_allocations_;
00428 }
00429 
00430 inline
00431 int WorkspaceStore::num_dyn_allocations() const
00432 {
00433   return num_dyn_allocations_;
00434 }
00435 
00436 inline
00437 size_t WorkspaceStore::num_current_bytes_total()
00438 {
00439   return num_current_bytes_total_;
00440 }
00441 
00442 inline
00443 size_t WorkspaceStore::num_max_bytes_needed() const
00444 {
00445   return num_max_bytes_needed_;
00446 }
00447 
00448 // /////////////////////////////////////////////////
00449 // Inline members for WorkspaceStoreInitializeable
00450 
00451 inline
00452 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes)
00453   : WorkspaceStore(num_bytes)
00454 {}
00455 
00456 inline
00457 void WorkspaceStoreInitializeable::initialize(size_t num_bytes)
00458 {
00459   protected_initialize(num_bytes);
00460 }
00461 
00462 // /////////////////////////////////////
00463 // Inline members for RawWorkspace
00464 
00465 inline
00466 size_t RawWorkspace::num_bytes() const
00467 {
00468   return workspace_end_ - workspace_begin_;
00469 }
00470 
00471 inline
00472 char* RawWorkspace::workspace_ptr()
00473 {
00474   return workspace_begin_;
00475 }
00476 
00477 inline
00478 const char* RawWorkspace::workspace_ptr() const
00479 {
00480   return workspace_begin_;
00481 }
00482 
00483 // should not have to define this but the gcc-2.95.2 compiler is complaining!
00484 inline
00485 void RawWorkspace::operator delete(void*)
00486 {
00487   assert(0);
00488 }
00489 
00490 } // end namespace Teuchos
00491 
00492 #endif // TEUCHOS_WORKSPACE_HPP

Generated on Thu Sep 18 12:41:18 2008 for Teuchos - Trilinos Tools Package by doxygen 1.3.9.1