Teuchos_Workspace.hpp

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 
00049 
00068 void set_default_workspace_store( const Teuchos::RefCountPtr<WorkspaceStore> &default_workspace_store );
00069 
00072 Teuchos::RefCountPtr<WorkspaceStore> get_default_workspace_store();
00073 
00081 void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out );
00082 
00087 class RawWorkspace {
00088 public:
00090   friend class WorkspaceStore;
00113   RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes);
00115   ~RawWorkspace();
00117   size_t num_bytes() const;
00119   char* workspace_ptr();
00121   const char* workspace_ptr() const;
00122 private:
00123   WorkspaceStore   *workspace_store_;
00124   char             *workspace_begin_;
00125   char             *workspace_end_;
00126   bool             owns_memory_;  // If true then the pointed to memory was allocated with
00127                                   // new so we need to call delete on it when we are destroyed.
00128   // not defined and not to be called
00129   RawWorkspace();
00130   RawWorkspace(const RawWorkspace&);
00131   RawWorkspace& operator=(const RawWorkspace&);
00132   static void* operator new(size_t);
00133   static void operator delete(void*);
00134 }; // end class RawWorkspace
00135 
00160 template<class T>
00161 class Workspace {
00162 public:
00194   Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true);
00198   ~Workspace();
00200   size_t size() const;
00207   T& operator[](size_t i);
00214   const T& operator[](size_t i) const;
00215 private:
00216   RawWorkspace  raw_workspace_;
00217   bool          call_constructors_;
00218   // not defined and not to be called
00219   Workspace();
00220   Workspace(const RawWorkspace&);
00221   Workspace& operator=(const RawWorkspace&);
00222   static void* operator new(size_t);
00223   static void operator delete(void*);
00224 }; // end class Workspace
00225 
00237 class WorkspaceStore {
00238 public:
00240   friend class RawWorkspace;
00242   ~WorkspaceStore();
00245   size_t num_bytes_total() const;
00248   size_t num_bytes_remaining() const;
00254   int num_static_allocations() const;
00260   int num_dyn_allocations() const;
00264   size_t num_current_bytes_total();
00268   size_t num_max_bytes_needed() const;
00269 protected:
00271   WorkspaceStore(size_t num_bytes);
00273   void protected_initialize(size_t num_bytes);
00274 private:
00275   char    *workspace_begin_; // Points to the beginning of raw allocated workspace.
00276                              // If NULL then no workspace has been allocated yet.
00277   char    *workspace_end_;   // Points to one past the last byte of allocated workspace.
00278                              // workspace_end_ >= workspace_begin_
00279   char    *curr_ws_ptr_;     // Points to the first available byte of workspace.
00280                              // workspace_begin_ <= curr_ws_ptr_ <= workspace_end_
00281   int     num_static_allocations_; // Number of workspace allocation using already
00282                              // allocated memory.
00283   int     num_dyn_allocations_; // Number of workspace allocations using dynamic
00284                              // memory because the current workspace store was
00285                              // overridden
00286   size_t  num_current_bytes_total_; // Total bytes currently being used
00287   size_t  num_max_bytes_needed_; // Maximum number of bytes of storage needed
00288   // Not definted and not to be called
00289   WorkspaceStore(const WorkspaceStore&);
00290   WorkspaceStore& operator=(const WorkspaceStore&);
00291 }; // end class WorkspaceStore
00292 
00300 class WorkspaceStoreInitializeable
00301   : public WorkspaceStore
00302 {
00303 public:
00307   WorkspaceStoreInitializeable(size_t num_bytes = 0);
00314   void initialize(size_t num_bytes);
00315 }; // end class WorkspaceStoreInitializeable
00316 
00318 
00319 // /////////////////////////////////////
00320 // Inline members for Workspace<T>
00321 
00322 template<class T>
00323 inline
00324 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors)
00325   : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors)
00326 {
00327   if(call_constructors_) {
00328     char* raw_ptr = raw_workspace_.workspace_ptr();
00329     for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00330       ::new (raw_ptr) T(); // placement new
00331   }
00332 }
00333 
00334 template<class T>
00335 inline
00336 Workspace<T>::~Workspace()
00337 {
00338   if(call_constructors_) {
00339     const size_t num_elements = this->size();
00340     char* raw_ptr = raw_workspace_.workspace_ptr();
00341     for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
00342       reinterpret_cast<T*>(raw_ptr)->~T();
00343   }
00344 }
00345 
00346 template<class T>
00347 inline
00348 size_t Workspace<T>::size() const
00349 {
00350   return raw_workspace_.num_bytes() / sizeof(T);
00351 }
00352 
00353 template<class T>
00354 inline
00355 T& Workspace<T>::operator[](size_t i)
00356 {
00357 #ifdef _DEBUG
00358   TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" );
00359 #endif  
00360   return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i];
00361 }
00362 
00363 template<class T>
00364 inline
00365 const T& Workspace<T>::operator[](size_t i) const
00366 {
00367   return const_cast<Workspace<T>*>(this)->operator[](i);
00368 }
00369 
00370 #ifdef __PGI // Should not have to define this but pgCC is complaining!
00371 template<class T>
00372 inline
00373 void* Workspace<T>::operator new(size_t)
00374 {
00375   assert(0);
00376   return NULL;
00377 }
00378 #endif
00379 
00380 // should not have to define this but the gcc-2.95.2 compiler is complaining!
00381 template<class T>
00382 inline
00383 void Workspace<T>::operator delete(void*)
00384 {
00385   assert(0);
00386 }
00387 
00388 // /////////////////////////////////////
00389 // Inline members for WorkspaceStore
00390 
00391 inline
00392 size_t WorkspaceStore::num_bytes_total() const
00393 {
00394   return workspace_end_ - workspace_begin_;
00395 }
00396 
00397 inline
00398 size_t WorkspaceStore::num_bytes_remaining() const
00399 {
00400   return workspace_end_ - curr_ws_ptr_;
00401 }
00402 
00403 inline
00404 int WorkspaceStore::num_static_allocations() const
00405 {
00406   return num_static_allocations_;
00407 }
00408 
00409 inline
00410 int WorkspaceStore::num_dyn_allocations() const
00411 {
00412   return num_dyn_allocations_;
00413 }
00414 
00415 inline
00416 size_t WorkspaceStore::num_current_bytes_total()
00417 {
00418   return num_current_bytes_total_;
00419 }
00420 
00421 inline
00422 size_t WorkspaceStore::num_max_bytes_needed() const
00423 {
00424   return num_max_bytes_needed_;
00425 }
00426 
00427 // /////////////////////////////////////////////////
00428 // Inline members for WorkspaceStoreInitializeable
00429 
00430 inline
00431 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes)
00432   : WorkspaceStore(num_bytes)
00433 {}
00434 
00435 inline
00436 void WorkspaceStoreInitializeable::initialize(size_t num_bytes)
00437 {
00438   protected_initialize(num_bytes);
00439 }
00440 
00441 // /////////////////////////////////////
00442 // Inline members for RawWorkspace
00443 
00444 inline
00445 size_t RawWorkspace::num_bytes() const
00446 {
00447   return workspace_end_ - workspace_begin_;
00448 }
00449 
00450 inline
00451 char* RawWorkspace::workspace_ptr()
00452 {
00453   return workspace_begin_;
00454 }
00455 
00456 inline
00457 const char* RawWorkspace::workspace_ptr() const
00458 {
00459   return workspace_begin_;
00460 }
00461 
00462 // should not have to define this but the gcc-2.95.2 compiler is complaining!
00463 inline
00464 void RawWorkspace::operator delete(void*)
00465 {
00466   assert(0);
00467 }
00468 
00469 } // end namespace Teuchos
00470 
00471 #endif // TEUCHOS_WORKSPACE_HPP

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