File: omp_alloc.cpp

package info (click to toggle)
cppad 2026.00.00.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,584 kB
  • sloc: cpp: 112,960; sh: 6,146; ansic: 179; python: 71; sed: 12; makefile: 10
file content (181 lines) | stat: -rw-r--r-- 5,489 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-22 Bradley M. Bell
// ----------------------------------------------------------------------------

/*
@begin omp_alloc.cpp@@
$spell
   openmp
$$

$section OpenMP Memory Allocator: Example and Test$$


$head Deprecated 2011-08-31$$
This example is only intended to help convert calls to $cref omp_alloc$$
to calls to $cref thread_alloc$$.

$srcthisfile%0%// BEGIN C++%// END C++%1%$$

$end
*/
// BEGIN C++
# include <cppad/utility/omp_alloc.hpp>
# include <cppad/utility/memory_leak.hpp>
# include <vector>

namespace { // Begin empty namespace

bool omp_alloc_bytes(void)
{  bool ok = true;
   using CppAD::omp_alloc;
   size_t thread;

   // check initial memory values
   ok &= ! CppAD::memory_leak();

   // amount of static memory used by thread zero
   size_t static_inuse = omp_alloc::inuse(0);

   // determine the currently executing thread
   // (should be zero because not in parallel mode)
   thread = omp_alloc::get_thread_num();

   // repeatedly allocate enough memory for at least two size_t values.
   size_t min_size_t = 2;
   size_t min_bytes  = min_size_t * sizeof(size_t);
   size_t n_outer   = 10;
   size_t n_inner    = 5;
   size_t cap_bytes(0), i, j, k;
   for(i = 0; i < n_outer; i++)
   {  // Do not use CppAD::vector here because its use of omp_alloc
      // complicates the inuse and available results.
      std::vector<void*> v_ptr(n_inner);
      for( j = 0; j < n_inner; j++)
      {  // allocate enough memory for min_size_t size_t objects
         v_ptr[j]    = omp_alloc::get_memory(min_bytes, cap_bytes);
         size_t* ptr = reinterpret_cast<size_t*>(v_ptr[j]);
         // determine the number of size_t values we have obtained
         size_t  cap_size_t = cap_bytes / sizeof(size_t);
         ok                &= min_size_t <= cap_size_t;
         // use placement new to call the size_t copy constructor
         for(k = 0; k < cap_size_t; k++)
            new(ptr + k) size_t(i + j + k);
         // check that the constructor worked
         for(k = 0; k < cap_size_t; k++)
            ok &= ptr[k] == (i + j + k);
      }
      // check that n_inner * cap_bytes are inuse and none are available
      ok &= omp_alloc::inuse(thread) == n_inner*cap_bytes + static_inuse;
      ok &= omp_alloc::available(thread) == 0;
      // return the memrory to omp_alloc
      for(j = 0; j < n_inner; j++)
         omp_alloc::return_memory(v_ptr[j]);
      // check that now n_inner * cap_bytes are now available
      // and none are in use
      ok &= omp_alloc::inuse(thread) == static_inuse;
      ok &= omp_alloc::available(thread) == n_inner * cap_bytes;
   }
   // return all the available memory to the system
   omp_alloc::free_available(thread);
   ok &= ! CppAD::memory_leak();

   return ok;
}

class my_char {
public:
   char ch_ ;
   my_char(void) : ch_(' ')
   { }
   my_char(const my_char& my_ch) : ch_(my_ch.ch_)
   { }
};

bool omp_alloc_array(void)
{  bool ok = true;
   using CppAD::omp_alloc;
   size_t i;

   // check initial memory values
   size_t thread = omp_alloc::get_thread_num();
   ok &= thread == 0;
   ok &= ! CppAD::memory_leak();
   size_t static_inuse = omp_alloc::inuse(0);

   // initial allocation of an array
   size_t  size_min  = 3;
   size_t  size_one;
   my_char *array_one  =
      omp_alloc::create_array<my_char>(size_min, size_one);

   // check the values and change them to null 'x'
   for(i = 0; i < size_one; i++)
   {  ok &= array_one[i].ch_ == ' ';
      array_one[i].ch_ = 'x';
   }

   // now create a longer array
   size_t size_two;
   my_char *array_two =
      omp_alloc::create_array<my_char>(2 * size_min, size_two);

   // check the values in array one
   for(i = 0; i < size_one; i++)
      ok &= array_one[i].ch_ == 'x';

   // check the values in array two
   for(i = 0; i < size_two; i++)
      ok &= array_two[i].ch_ == ' ';

   // check the amount of inuse and available memory
   // (an extra size_t value is used for each memory block).
   size_t check = static_inuse + sizeof(my_char)*(size_one + size_two);
   ok   &= omp_alloc::inuse(thread) - check < sizeof(my_char);
   ok   &= omp_alloc::available(thread) == 0;

   // delete the arrays
   omp_alloc::delete_array(array_one);
   omp_alloc::delete_array(array_two);
   ok   &= omp_alloc::inuse(thread) == static_inuse;
   check = sizeof(my_char)*(size_one + size_two);
   ok   &= omp_alloc::available(thread) - check < sizeof(my_char);

   // free the memory for use by this thread
   omp_alloc::free_available(thread);
   ok &= ! CppAD::memory_leak();

   return ok;
}
} // End empty namespace

bool omp_alloc(void)
{  bool ok  = true;
   using CppAD::omp_alloc;

   // check initial state of allocator
   ok  &= omp_alloc::get_max_num_threads() == 1;

   // set the maximum number of threads greater than one
   // so that omp_alloc holds onto memory
   CppAD::omp_alloc::set_max_num_threads(2);
   ok  &= omp_alloc::get_max_num_threads() == 2;
   ok  &= ! CppAD::memory_leak();

   // now use memory allocator in state where it holds onto memory
   ok   &= omp_alloc_bytes();
   ok   &= omp_alloc_array();

   // check that the tests have not held onto memory
   ok  &= ! CppAD::memory_leak();

   // set the maximum number of threads back to one
   // so that omp_alloc no longer holds onto memory
   CppAD::omp_alloc::set_max_num_threads(1);

   return ok;
}


// END C++