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

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