|
Teuchos - Trilinos Tools Package
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 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef TEUCHOS_WORKSPACE_HPP 00043 #define TEUCHOS_WORKSPACE_HPP 00044 00045 #include "Teuchos_RCP.hpp" 00046 #include "Teuchos_ArrayView.hpp" 00047 #include "Teuchos_Assert.hpp" 00048 00049 namespace Teuchos { 00050 00051 class WorkspaceStore; 00052 class RawWorkspace; 00053 00065 00084 TEUCHOSCORE_LIB_DLL_EXPORT void set_default_workspace_store( const Teuchos::RCP<WorkspaceStore> &default_workspace_store ); 00085 00088 TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP<WorkspaceStore> get_default_workspace_store(); 00089 00097 TEUCHOSCORE_LIB_DLL_EXPORT void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out ); 00098 00103 class TEUCHOSCORE_LIB_DLL_EXPORT RawWorkspace { 00104 public: 00106 friend class WorkspaceStore; 00129 RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes); 00131 ~RawWorkspace(); 00133 size_t num_bytes() const; 00135 char* workspace_ptr(); 00137 const char* workspace_ptr() const; 00138 private: 00139 WorkspaceStore *workspace_store_; 00140 char *workspace_begin_; 00141 char *workspace_end_; 00142 bool owns_memory_; // If true then the pointed to memory was allocated with 00143 // new so we need to call delete on it when we are destroyed. 00144 // not defined and not to be called 00145 RawWorkspace(); 00146 RawWorkspace(const RawWorkspace&); 00147 RawWorkspace& operator=(const RawWorkspace&); 00148 static void* operator new(size_t); 00149 static void operator delete(void*); 00150 }; // end class RawWorkspace 00151 00176 template<class T> 00177 class Workspace { 00178 public: 00210 Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true); 00214 ~Workspace(); 00216 size_t size() const; 00219 T* getRawPtr(); 00222 const T* getRawPtr() const; 00229 T& operator[](size_t i); 00236 const T& operator[](size_t i) const; 00238 ArrayView<T> operator()(); 00240 ArrayView<const T> operator()() const; 00242 operator ArrayView<T>(); 00244 operator ArrayView<const T>() const; 00245 private: 00246 RawWorkspace raw_workspace_; 00247 bool call_constructors_; 00248 // not defined and not to be called 00249 Workspace(); 00250 Workspace(const RawWorkspace&); 00251 Workspace& operator=(const RawWorkspace&); 00252 static void* operator new(size_t); 00253 static void operator delete(void*); 00254 }; // end class Workspace 00255 00267 class TEUCHOSCORE_LIB_DLL_EXPORT WorkspaceStore { 00268 public: 00270 friend class RawWorkspace; 00272 ~WorkspaceStore(); 00275 size_t num_bytes_total() const; 00278 size_t num_bytes_remaining() const; 00284 int num_static_allocations() const; 00290 int num_dyn_allocations() const; 00294 size_t num_current_bytes_total(); 00298 size_t num_max_bytes_needed() const; 00299 protected: 00301 WorkspaceStore(size_t num_bytes); 00303 void protected_initialize(size_t num_bytes); 00304 private: 00305 char *workspace_begin_; // Points to the beginning of raw allocated workspace. 00306 // If NULL then no workspace has been allocated yet. 00307 char *workspace_end_; // Points to one past the last byte of allocated workspace. 00308 // workspace_end_ >= workspace_begin_ 00309 char *curr_ws_ptr_; // Points to the first available byte of workspace. 00310 // workspace_begin_ <= curr_ws_ptr_ <= workspace_end_ 00311 int num_static_allocations_; // Number of workspace allocation using already 00312 // allocated memory. 00313 int num_dyn_allocations_; // Number of workspace allocations using dynamic 00314 // memory because the current workspace store was 00315 // overridden 00316 size_t num_current_bytes_total_; // Total bytes currently being used 00317 size_t num_max_bytes_needed_; // Maximum number of bytes of storage needed 00318 // Not definted and not to be called 00319 WorkspaceStore(const WorkspaceStore&); 00320 WorkspaceStore& operator=(const WorkspaceStore&); 00321 }; // end class WorkspaceStore 00322 00330 class WorkspaceStoreInitializeable 00331 : public WorkspaceStore 00332 { 00333 public: 00337 WorkspaceStoreInitializeable(size_t num_bytes = 0); 00344 void initialize(size_t num_bytes); 00345 }; // end class WorkspaceStoreInitializeable 00346 00348 00349 // ///////////////////////////////////// 00350 // Inline members for Workspace<T> 00351 00352 template<class T> 00353 inline 00354 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors) 00355 : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors) 00356 { 00357 if(call_constructors_) { 00358 char* raw_ptr = raw_workspace_.workspace_ptr(); 00359 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) ) 00360 ::new (raw_ptr) T(); // placement new 00361 } 00362 } 00363 00364 template<class T> 00365 inline 00366 Workspace<T>::~Workspace() 00367 { 00368 if(call_constructors_) { 00369 const size_t num_elements = this->size(); 00370 char* raw_ptr = raw_workspace_.workspace_ptr(); 00371 for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) ) 00372 reinterpret_cast<T*>(raw_ptr)->~T(); 00373 } 00374 } 00375 00376 template<class T> 00377 inline 00378 size_t Workspace<T>::size() const 00379 { 00380 return raw_workspace_.num_bytes() / sizeof(T); 00381 } 00382 00383 template<class T> 00384 inline 00385 T* Workspace<T>::getRawPtr() 00386 { 00387 return ( size() ? &(*this)[0] : 0 ); 00388 } 00389 00390 template<class T> 00391 inline 00392 const T* Workspace<T>::getRawPtr() const 00393 { 00394 return ( size() ? &(*this)[0] : 0 ); 00395 } 00396 00397 template<class T> 00398 inline 00399 T& Workspace<T>::operator[](size_t i) 00400 { 00401 #ifdef TEUCHOS_DEBUG 00402 TEUCHOS_TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" ); 00403 #endif 00404 return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i]; 00405 } 00406 00407 template<class T> 00408 inline 00409 const T& Workspace<T>::operator[](size_t i) const 00410 { 00411 return const_cast<Workspace<T>*>(this)->operator[](i); 00412 } 00413 00414 template<class T> 00415 inline 00416 ArrayView<T> Workspace<T>::operator()() 00417 { 00418 if (size()==0) 00419 return Teuchos::null; 00420 return arrayView<T>( &(*this)[0], size() ); 00421 } 00422 00423 template<class T> 00424 inline 00425 ArrayView<const T> 00426 Workspace<T>::operator()() const 00427 { 00428 if (size()==0) 00429 return Teuchos::null; 00430 return arrayView<const T>( &(*this)[0], size() ); 00431 } 00432 00433 template<class T> 00434 inline 00435 Workspace<T>::operator ArrayView<T>() 00436 { 00437 return (*this)(); 00438 } 00439 00440 template<class T> 00441 inline 00442 Workspace<T>::operator ArrayView<const T>() const 00443 { 00444 return (*this)(); 00445 } 00446 00447 #ifdef __PGI // Should not have to define this but pgCC is complaining! 00448 template<class T> 00449 inline 00450 void* Workspace<T>::operator new(size_t) 00451 { 00452 assert(0); 00453 return NULL; 00454 } 00455 #endif 00456 00457 // should not have to define this but the gcc-2.95.2 compiler is complaining! 00458 template<class T> 00459 inline 00460 void Workspace<T>::operator delete(void*) 00461 { 00462 assert(0); 00463 } 00464 00465 // ///////////////////////////////////// 00466 // Inline members for WorkspaceStore 00467 00468 inline 00469 size_t WorkspaceStore::num_bytes_total() const 00470 { 00471 return workspace_end_ - workspace_begin_; 00472 } 00473 00474 inline 00475 size_t WorkspaceStore::num_bytes_remaining() const 00476 { 00477 return workspace_end_ - curr_ws_ptr_; 00478 } 00479 00480 inline 00481 int WorkspaceStore::num_static_allocations() const 00482 { 00483 return num_static_allocations_; 00484 } 00485 00486 inline 00487 int WorkspaceStore::num_dyn_allocations() const 00488 { 00489 return num_dyn_allocations_; 00490 } 00491 00492 inline 00493 size_t WorkspaceStore::num_current_bytes_total() 00494 { 00495 return num_current_bytes_total_; 00496 } 00497 00498 inline 00499 size_t WorkspaceStore::num_max_bytes_needed() const 00500 { 00501 return num_max_bytes_needed_; 00502 } 00503 00504 // ///////////////////////////////////////////////// 00505 // Inline members for WorkspaceStoreInitializeable 00506 00507 inline 00508 WorkspaceStoreInitializeable::WorkspaceStoreInitializeable(size_t num_bytes) 00509 : WorkspaceStore(num_bytes) 00510 {} 00511 00512 inline 00513 void WorkspaceStoreInitializeable::initialize(size_t num_bytes) 00514 { 00515 protected_initialize(num_bytes); 00516 } 00517 00518 // ///////////////////////////////////// 00519 // Inline members for RawWorkspace 00520 00521 inline 00522 size_t RawWorkspace::num_bytes() const 00523 { 00524 return workspace_end_ - workspace_begin_; 00525 } 00526 00527 inline 00528 char* RawWorkspace::workspace_ptr() 00529 { 00530 return workspace_begin_; 00531 } 00532 00533 inline 00534 const char* RawWorkspace::workspace_ptr() const 00535 { 00536 return workspace_begin_; 00537 } 00538 00539 // should not have to define this but the gcc-2.95.2 compiler is complaining! 00540 inline 00541 void RawWorkspace::operator delete(void*) 00542 { 00543 assert(0); 00544 } 00545 00546 } // end namespace Teuchos 00547 00548 #endif // TEUCHOS_WORKSPACE_HPP
1.7.6.1