Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_Workspace.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef TEUCHOS_WORKSPACE_HPP
43 #define TEUCHOS_WORKSPACE_HPP
44 
45 #include "Teuchos_RCP.hpp"
46 #include "Teuchos_ArrayView.hpp"
47 #include "Teuchos_Assert.hpp"
48 
49 namespace Teuchos {
50 
51 class WorkspaceStore;
52 class RawWorkspace;
53 
65 
84 TEUCHOSCORE_LIB_DLL_EXPORT void set_default_workspace_store( const Teuchos::RCP<WorkspaceStore> &default_workspace_store );
85 
89 
97 TEUCHOSCORE_LIB_DLL_EXPORT void print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out );
98 
103 class TEUCHOSCORE_LIB_DLL_EXPORT RawWorkspace {
104 public:
106  friend class WorkspaceStore;
129  RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes);
131  ~RawWorkspace();
133  size_t num_bytes() const;
135  char* workspace_ptr();
137  const char* workspace_ptr() const;
138 private:
139  WorkspaceStore *workspace_store_;
140  char *workspace_begin_;
141  char *workspace_end_;
142  bool owns_memory_; // If true then the pointed to memory was allocated with
143  // new so we need to call delete on it when we are destroyed.
144  // not defined and not to be called
145  RawWorkspace();
146  RawWorkspace(const RawWorkspace&);
147  RawWorkspace& operator=(const RawWorkspace&);
148  static void* operator new(size_t);
149  static void operator delete(void*);
150 }; // end class RawWorkspace
151 
176 template<class T>
177 class Workspace {
178 public:
210  Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors = true);
214  ~Workspace();
216  size_t size() const;
219  T* getRawPtr();
222  const T* getRawPtr() const;
229  T& operator[](size_t i);
236  const T& operator[](size_t i) const;
242  operator ArrayView<T>();
244  operator ArrayView<const T>() const;
245 private:
246  RawWorkspace raw_workspace_;
247  bool call_constructors_;
248  // not defined and not to be called
249  Workspace();
250  Workspace(const RawWorkspace&);
251  Workspace& operator=(const RawWorkspace&);
252  static void* operator new(size_t);
253  static void operator delete(void*);
254 }; // end class Workspace
255 
267 class TEUCHOSCORE_LIB_DLL_EXPORT WorkspaceStore {
268 public:
270  friend class RawWorkspace;
272  ~WorkspaceStore();
275  size_t num_bytes_total() const;
278  size_t num_bytes_remaining() const;
284  int num_static_allocations() const;
290  int num_dyn_allocations() const;
294  size_t num_current_bytes_total();
298  size_t num_max_bytes_needed() const;
299 protected:
301  WorkspaceStore(size_t num_bytes);
303  void protected_initialize(size_t num_bytes);
304 private:
305  char *workspace_begin_; // Points to the beginning of raw allocated workspace.
306  // If NULL then no workspace has been allocated yet.
307  char *workspace_end_; // Points to one past the last byte of allocated workspace.
308  // workspace_end_ >= workspace_begin_
309  char *curr_ws_ptr_; // Points to the first available byte of workspace.
310  // workspace_begin_ <= curr_ws_ptr_ <= workspace_end_
311  int num_static_allocations_; // Number of workspace allocation using already
312  // allocated memory.
313  int num_dyn_allocations_; // Number of workspace allocations using dynamic
314  // memory because the current workspace store was
315  // overridden
316  size_t num_current_bytes_total_; // Total bytes currently being used
317  size_t num_max_bytes_needed_; // Maximum number of bytes of storage needed
318  // Not definted and not to be called
320  WorkspaceStore& operator=(const WorkspaceStore&);
321 }; // end class WorkspaceStore
322 
331  : public WorkspaceStore
332 {
333 public:
337  WorkspaceStoreInitializeable(size_t num_bytes = 0);
344  void initialize(size_t num_bytes);
345 }; // end class WorkspaceStoreInitializeable
346 
348 
349 // /////////////////////////////////////
350 // Inline members for Workspace<T>
351 
352 template<class T>
353 inline
354 Workspace<T>::Workspace(WorkspaceStore* workspace_store, size_t num_elements, bool call_constructors)
355  : raw_workspace_(workspace_store,sizeof(T)*num_elements), call_constructors_(call_constructors)
356 {
357  if(call_constructors_) {
358  char* raw_ptr = raw_workspace_.workspace_ptr();
359  for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
360  ::new (raw_ptr) T(); // placement new
361  }
362 }
363 
364 template<class T>
365 inline
367 {
368  if(call_constructors_) {
369  const size_t num_elements = this->size();
370  char* raw_ptr = raw_workspace_.workspace_ptr();
371  for( size_t k = 0; k < num_elements; ++k, raw_ptr += sizeof(T) )
372  reinterpret_cast<T*>(raw_ptr)->~T();
373  }
374 }
375 
376 template<class T>
377 inline
378 size_t Workspace<T>::size() const
379 {
380  return raw_workspace_.num_bytes() / sizeof(T);
381 }
382 
383 template<class T>
384 inline
386 {
387  return ( size() ? &(*this)[0] : 0 );
388 }
389 
390 template<class T>
391 inline
392 const T* Workspace<T>::getRawPtr() const
393 {
394  return ( size() ? &(*this)[0] : 0 );
395 }
396 
397 template<class T>
398 inline
400 {
401 #ifdef TEUCHOS_DEBUG
402  TEUCHOS_TEST_FOR_EXCEPTION( !( i < this->size() ), std::invalid_argument, "Workspace<T>::operator[](i): Error!" );
403 #endif
404  return reinterpret_cast<T*>(raw_workspace_.workspace_ptr())[i];
405 }
406 
407 template<class T>
408 inline
409 const T& Workspace<T>::operator[](size_t i) const
410 {
411  return const_cast<Workspace<T>*>(this)->operator[](i);
412 }
413 
414 template<class T>
415 inline
417 {
418  if (size()==0)
419  return Teuchos::null;
420  return arrayView<T>( &(*this)[0], size() );
421 }
422 
423 template<class T>
424 inline
427 {
428  if (size()==0)
429  return Teuchos::null;
430  return arrayView<const T>( &(*this)[0], size() );
431 }
432 
433 template<class T>
434 inline
436 {
437  return (*this)();
438 }
439 
440 template<class T>
441 inline
443 {
444  return (*this)();
445 }
446 
447 #ifdef __PGI // Should not have to define this but pgCC is complaining!
448 template<class T>
449 inline
450 void* Workspace<T>::operator new(size_t)
451 {
452  assert(0);
453  return NULL;
454 }
455 #endif
456 
457 // should not have to define this but the gcc-2.95.2 compiler is complaining!
458 template<class T>
459 inline
460 void Workspace<T>::operator delete(void*)
461 {
462  assert(0);
463 }
464 
465 // /////////////////////////////////////
466 // Inline members for WorkspaceStore
467 
468 inline
470 {
471  return workspace_end_ - workspace_begin_;
472 }
473 
474 inline
476 {
477  return workspace_end_ - curr_ws_ptr_;
478 }
479 
480 inline
482 {
483  return num_static_allocations_;
484 }
485 
486 inline
488 {
489  return num_dyn_allocations_;
490 }
491 
492 inline
494 {
495  return num_current_bytes_total_;
496 }
497 
498 inline
500 {
501  return num_max_bytes_needed_;
502 }
503 
504 // /////////////////////////////////////////////////
505 // Inline members for WorkspaceStoreInitializeable
506 
507 inline
509  : WorkspaceStore(num_bytes)
510 {}
511 
512 inline
514 {
515  protected_initialize(num_bytes);
516 }
517 
518 // /////////////////////////////////////
519 // Inline members for RawWorkspace
520 
521 inline
523 {
524  return workspace_end_ - workspace_begin_;
525 }
526 
527 inline
529 {
530  return workspace_begin_;
531 }
532 
533 inline
534 const char* RawWorkspace::workspace_ptr() const
535 {
536  return workspace_begin_;
537 }
538 
539 // should not have to define this but the gcc-2.95.2 compiler is complaining!
540 inline
541 void RawWorkspace::operator delete(void*)
542 {
543  assert(0);
544 }
545 
546 } // end namespace Teuchos
547 
548 #endif // TEUCHOS_WORKSPACE_HPP
WorkspaceStoreInitializeable(size_t num_bytes=0)
Default constructs to no memory set and will dynamically allocate all memory requested.
size_t size() const
Return the number of elements in the array.
Encapulsation object for raw temporary workspace that has been allocated. These objects can only be c...
Templated class for workspace creation.
ArrayView< T > operator()()
Return a non-const array view.
~Workspace()
The destructor on the elements will only be called if call_constructors == true was passed to the con...
TEUCHOSCORE_LIB_DLL_EXPORT void set_default_workspace_store(const Teuchos::RCP< WorkspaceStore > &default_workspace_store)
Set pointer to global workspace object.
WorkspaceStore class that can be used to actually reinitialize memory.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
size_t num_bytes() const
Return the number of bytes of raw workspace.
size_t num_current_bytes_total()
Return the total number of bytes currently allocated.. This is the total number of bytes currently be...
T & operator[](size_t i)
Non-const zero based element access.
T * getRawPtr()
Return a raw pointer to the beginning of the array or null if unsized.
Workspace encapsulation class.
Nonowning array view.
size_t num_max_bytes_needed() const
Return the maximum storage in bytes needed. This is the maximum total amount of * storage that was ne...
int num_dyn_allocations() const
Return the number of dynamic memory allocations granted thus far. This is the number of memory alloca...
int num_static_allocations() const
Return the number of static memory allocations granted thus far. This is the number of memory allocat...
Smart reference counting pointer class for automatic garbage collection.
void initialize(size_t num_bytes)
Set the size block of memory to be given as workspace.
void protected_initialize(size_t num_bytes)
Partial specialization of ArrayView for const T.
char * workspace_ptr()
Give a raw pointer to the beginning of the workspace.
size_t num_bytes_remaining() const
Return the number of bytes remaining currently.
size_t num_bytes_total() const
Return the total number of bytes that where initially allocated.
TEUCHOSCORE_LIB_DLL_EXPORT void print_memory_usage_stats(const WorkspaceStore *workspace_store, std::ostream &out)
Print statistics on memory usage.
Reference-counted pointer class and non-member templated function implementations.
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()
Get the global workspace object set by set_default_workspace_store().