|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
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_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 TEUCHOS_LIB_DLL_EXPORT void set_default_workspace_store( const Teuchos::RCP<WorkspaceStore> &default_workspace_store ); 00072 00075 TEUCHOS_LIB_DLL_EXPORT Teuchos::RCP<WorkspaceStore> get_default_workspace_store(); 00076 00084 TEUCHOS_LIB_DLL_EXPORT void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out ); 00085 00090 class TEUCHOS_LIB_DLL_EXPORT 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_; // If true then the pointed to memory was allocated with 00130 // new so we need to call delete on it when we are destroyed. 00131 // not defined and not to be called 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 }; // end class RawWorkspace 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 ArrayView<T> operator()(); 00227 ArrayView<const T> operator()() const; 00229 operator ArrayView<T>(); 00231 operator ArrayView<const T>() const; 00232 private: 00233 RawWorkspace raw_workspace_; 00234 bool call_constructors_; 00235 // not defined and not to be called 00236 Workspace(); 00237 Workspace(const RawWorkspace&); 00238 Workspace& operator=(const RawWorkspace&); 00239 static void* operator new(size_t); 00240 static void operator delete(void*); 00241 }; // end class Workspace 00242 00254 class TEUCHOS_LIB_DLL_EXPORT WorkspaceStore { 00255 public: 00257 friend class RawWorkspace; 00259 ~WorkspaceStore(); 00262 size_t num_bytes_total() const; 00265 size_t num_bytes_remaining() const; 00271 int num_static_allocations() const; 00277 int num_dyn_allocations() const; 00281 size_t num_current_bytes_total(); 00285 size_t num_max_bytes_needed() const; 00286 protected: 00288 WorkspaceStore(size_t num_bytes); 00290 void protected_initialize(size_t num_bytes); 00291 private: 00292 char *workspace_begin_; // Points to the beginning of raw allocated workspace. 00293 // If NULL then no workspace has been allocated yet. 00294 char *workspace_end_; // Points to one past the last byte of allocated workspace. 00295 // workspace_end_ >= workspace_begin_ 00296 char *curr_ws_ptr_; // Points to the first available byte of workspace. 00297 // workspace_begin_ <= curr_ws_ptr_ <= workspace_end_ 00298 int num_static_allocations_; // Number of workspace allocation using already 00299 // allocated memory. 00300 int num_dyn_allocations_; // Number of workspace allocations using dynamic 00301 // memory because the current workspace store was 00302 // overridden 00303 size_t num_current_bytes_total_; // Total bytes currently being used 00304 size_t num_max_bytes_needed_; // Maximum number of bytes of storage needed 00305 // Not definted and not to be called 00306 WorkspaceStore(const WorkspaceStore&); 00307 WorkspaceStore& operator=(const WorkspaceStore&); 00308 }; // end class WorkspaceStore 00309 00317 class WorkspaceStoreInitializeable 00318 : public WorkspaceStore 00319 { 00320 public: 00324 WorkspaceStoreInitializeable(size_t num_bytes = 0); 00331 void initialize(size_t num_bytes); 00332 }; // end class WorkspaceStoreInitializeable 00333 00335 00336 // ///////////////////////////////////// 00337 // Inline members for Workspace<T> 00338 00339 template<class T> 00340 inline 00341 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors) 00342 : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors) 00343 { 00344 if(call_constructors_) { 00345 char* raw_ptr = raw_workspace_.workspace_ptr(); 00346 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) ) 00347 ::new (raw_ptr) T(); // placement new 00348 } 00349 } 00350 00351 template<class T> 00352 inline 00353 Workspace<T>::~Workspace() 00354 { 00355 if(call_constructors_) { 00356 const size_t num_elements = this->size(); 00357 char* raw_ptr = raw_workspace_.workspace_ptr(); 00358 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) ) 00359 reinterpret_cast<T*>(raw_ptr)->~T(); 00360 } 00361 } 00362 00363 template<class T> 00364 inline 00365 size_t Workspace<T>::size() const 00366 { 00367 return raw_workspace_.num_bytes() / sizeof(T); 00368 } 00369 00370 template<class T> 00371 inline 00372 T* Workspace<T>::getRawPtr() 00373 { 00374 return ( size() ? &(*this)[0] : 0 ); 00375 } 00376 00377 template<class T> 00378 inline 00379 const T* Workspace<T>::getRawPtr() const 00380 { 00381 return ( size() ? &(*this)[0] : 0 ); 00382 } 00383 00384 template<class T> 00385 inline 00386 T& Workspace<T>::operator[](size_t i) 00387 { 00388 #ifdef TEUCHOS_DEBUG 00389 TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" ); 00390 #endif 00391 return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i]; 00392 } 00393 00394 template<class T> 00395 inline 00396 const T& Workspace<T>::operator[](size_t i) const 00397 { 00398 return const_cast<Workspace<T>*>(this)->operator[](i); 00399 } 00400 00401 template<class T> 00402 inline 00403 ArrayView<T> Workspace<T>::operator()() 00404 { 00405 if (size()==0) 00406 return Teuchos::null; 00407 return arrayView<T>( &(*this)[0], size() ); 00408 } 00409 00410 template<class T> 00411 inline 00412 ArrayView<const T> 00413 Workspace<T>::operator()() const 00414 { 00415 if (size()==0) 00416 return Teuchos::null; 00417 return arrayView<const T>( &(*this)[0], size() ); 00418 } 00419 00420 template<class T> 00421 inline 00422 Workspace<T>::operator ArrayView<T>() 00423 { 00424 return (*this)(); 00425 } 00426 00427 template<class T> 00428 inline 00429 Workspace<T>::operator ArrayView<const T>() const 00430 { 00431 return (*this)(); 00432 } 00433 00434 #ifdef __PGI // Should not have to define this but pgCC is complaining! 00435 template<class T> 00436 inline 00437 void* Workspace<T>::operator new(size_t) 00438 { 00439 assert(0); 00440 return NULL; 00441 } 00442 #endif 00443 00444 // should not have to define this but the gcc-2.95.2 compiler is complaining! 00445 template<class T> 00446 inline 00447 void Workspace<T>::operator delete(void*) 00448 { 00449 assert(0); 00450 } 00451 00452 // ///////////////////////////////////// 00453 // Inline members for WorkspaceStore 00454 00455 inline 00456 size_t WorkspaceStore::num_bytes_total() const 00457 { 00458 return workspace_end_ - workspace_begin_; 00459 } 00460 00461 inline 00462 size_t WorkspaceStore::num_bytes_remaining() const 00463 { 00464 return workspace_end_ - curr_ws_ptr_; 00465 } 00466 00467 inline 00468 int WorkspaceStore::num_static_allocations() const 00469 { 00470 return num_static_allocations_; 00471 } 00472 00473 inline 00474 int WorkspaceStore::num_dyn_allocations() const 00475 { 00476 return num_dyn_allocations_; 00477 } 00478 00479 inline 00480 size_t WorkspaceStore::num_current_bytes_total() 00481 { 00482 return num_current_bytes_total_; 00483 } 00484 00485 inline 00486 size_t WorkspaceStore::num_max_bytes_needed() const 00487 { 00488 return num_max_bytes_needed_; 00489 } 00490 00491 // ///////////////////////////////////////////////// 00492 // Inline members for WorkspaceStoreInitializeable 00493 00494 inline 00495 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes) 00496 : WorkspaceStore(num_bytes) 00497 {} 00498 00499 inline 00500 void WorkspaceStoreInitializeable::initialize(size_t num_bytes) 00501 { 00502 protected_initialize(num_bytes); 00503 } 00504 00505 // ///////////////////////////////////// 00506 // Inline members for RawWorkspace 00507 00508 inline 00509 size_t RawWorkspace::num_bytes() const 00510 { 00511 return workspace_end_ - workspace_begin_; 00512 } 00513 00514 inline 00515 char* RawWorkspace::workspace_ptr() 00516 { 00517 return workspace_begin_; 00518 } 00519 00520 inline 00521 const char* RawWorkspace::workspace_ptr() const 00522 { 00523 return workspace_begin_; 00524 } 00525 00526 // should not have to define this but the gcc-2.95.2 compiler is complaining! 00527 inline 00528 void RawWorkspace::operator delete(void*) 00529 { 00530 assert(0); 00531 } 00532 00533 } // end namespace Teuchos 00534 00535 #endif // TEUCHOS_WORKSPACE_HPP
1.7.4