Teuchos - Trilinos Tools Package  Version of the Day
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_, std::logic_error
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.
~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...
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
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_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().