Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_Workspace.cpp
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 #include "Teuchos_Workspace.hpp"
43 
44 namespace {
45 Teuchos::RCP<Teuchos::WorkspaceStore> default_workspace_store(Teuchos::null);
46 }
47 
48 // Global functions
49 
50 void Teuchos::set_default_workspace_store( const Teuchos::RCP<WorkspaceStore> &default_workspace_store_in )
51 {
52  default_workspace_store = default_workspace_store_in;
53 }
54 
56 {
57  return default_workspace_store;
58 }
59 
60 void Teuchos::print_memory_usage_stats( const WorkspaceStore* workspace_store, std::ostream& out )
61 {
62  if( workspace_store ) {
63  out
64  << "\n*** Statistics for autmatic array workspace:"
65  << "\n Number of megabytes of preallocated workspace = "
66  << (workspace_store->num_bytes_total()*1e-6)
67  << "\n Number of megabytes needed = "
68  << (workspace_store->num_max_bytes_needed()*1e-6)
69  << "\n Number of allocations using preallocated workspace = "
70  << workspace_store->num_static_allocations()
71  << "\n Number of dynamic allocations beyond preallocated workspace = "
72  << workspace_store->num_dyn_allocations()
73  << "\n";
74  }
75  else {
76  out
77  << "\n*** Statistics for autmatic array workspace:"
78  << "\n No workspace storage was allocated!\n";
79  }
80 }
81 
82 namespace Teuchos {
83 
84 // WorkspaceStore
85 
87  : workspace_begin_(NULL)
88  , workspace_end_(NULL)
89  , curr_ws_ptr_(NULL)
90  , num_static_allocations_(0)
91  , num_dyn_allocations_(0)
92  , num_current_bytes_total_(0)
93  , num_max_bytes_needed_(0)
94 {
95  if(num_bytes)
96  protected_initialize(num_bytes);
97 }
98 
100  if(workspace_begin_) delete [] workspace_begin_;
101 }
102 
104 {
106  curr_ws_ptr_ != workspace_begin_, std::logic_error
107  ,"WorkspaceStore::set_workspace_size(...) : Error, "
108  "You can not reset the workspace size when any RawWorkspace objects "
109  "are using workspace!" );
110  if(workspace_begin_) delete [] workspace_begin_;
111  workspace_begin_ = ::new char[num_bytes];
112  workspace_end_ = workspace_begin_ + num_bytes;
113  curr_ws_ptr_ = workspace_begin_;
114  num_static_allocations_ = 0;
115  num_dyn_allocations_ = 0;
116  num_current_bytes_total_= 0;
117  num_max_bytes_needed_ = 0;
118 }
119 
120 // RawWorkspace
121 
122 RawWorkspace::RawWorkspace(WorkspaceStore* workspace_store, size_t num_bytes_in)
123 {
124  if(num_bytes_in) {
125  workspace_store_ = workspace_store;
126  if( !workspace_store_ || workspace_store_->num_bytes_remaining() < num_bytes_in ) {
127  workspace_begin_ = ::new char[num_bytes_in];
128  workspace_end_ = workspace_begin_ + num_bytes_in;
129  owns_memory_ = true;
130  if(workspace_store_)
131  workspace_store_->num_dyn_allocations_++;
132  }
133  else {
134  workspace_begin_ = workspace_store_->curr_ws_ptr_;
135  workspace_end_ = workspace_begin_ + num_bytes_in;
136  owns_memory_ = false;
137  workspace_store_->curr_ws_ptr_ += num_bytes_in;
138  workspace_store_->num_static_allocations_++;
139  }
140  }
141  else {
142  workspace_store_ = NULL;
143  workspace_begin_ = NULL;
144  workspace_end_ = NULL;
145  owns_memory_ = false;
146  }
147  if(workspace_store_) {
148  workspace_store_->num_current_bytes_total_ += num_bytes_in;
149  if( workspace_store_->num_current_bytes_total_ > workspace_store_->num_max_bytes_needed_ )
150  workspace_store_->num_max_bytes_needed_ = workspace_store_->num_current_bytes_total_;
151  }
152 }
153 
155 {
156  if(workspace_store_)
157  workspace_store_->num_current_bytes_total_ -= this->num_bytes();
158  if(owns_memory_) {
159  if(workspace_begin_) delete [] workspace_begin_;
160  }
161  else {
162  if(workspace_store_) {
164  workspace_store_->curr_ws_ptr_ != workspace_end_
165  ,"RawWorkspace::~RawWorkspace(...): Error, "
166  "Invalid usage of RawWorkspace class, corrupted WorspaceStore object!" );
167  workspace_store_->curr_ws_ptr_ = workspace_begin_;
168  }
169  }
170 }
171 
172 #ifdef __PGI // Should not have to define this since it should not be called!
173 void* RawWorkspace::operator new(size_t)
174 {
175  assert(0);
176  return NULL;
177 }
178 #endif
179 
180 } // end namespace Teuchos
TEUCHOSCORE_LIB_DLL_EXPORT void set_default_workspace_store(const Teuchos::RCP< WorkspaceStore > &default_workspace_store)
Set pointer to global workspace object.
#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.
~RawWorkspace()
Deallocate workspace.
WorkspaceStore(size_t num_bytes)
Workspace encapsulation class.
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...
#define TEUCHOS_TEST_FOR_TERMINATION(terminate_test, msg)
This macro is to be used instead of TEUCHOS_TEST_FOR_EXCEPTION() to report an error in situations whe...
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 protected_initialize(size_t num_bytes)
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.
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()
Get the global workspace object set by set_default_workspace_store().