1 // $Id: omp_alloc.hpp 3804 2016-03-20 15:08:46Z bradbell $
2 # ifndef CPPAD_UTILITY_OMP_ALLOC_HPP
3 # define CPPAD_UTILITY_OMP_ALLOC_HPP
4 
5 /* --------------------------------------------------------------------------
6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 Bradley M. Bell
7 
8 CppAD is distributed under multiple licenses. This distribution is under
9 the terms of the
10                     Eclipse Public License Version 1.0.
11 
12 A copy of this license is included in the COPYING file of this distribution.
13 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14 -------------------------------------------------------------------------- */
15 # include <cppad/utility/thread_alloc.hpp>
16 # ifdef _OPENMP
17 # include <omp.h>
18 # endif
19 
20 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
21 class omp_alloc{
22 // ============================================================================
23 public:
24 /*
25 $begin omp_max_num_threads$$
26 $spell
27 	cppad.hpp
28 	inv
29 	CppAD
30 	num
31 	omp_alloc
32 $$
33 $section Set and Get Maximum Number of Threads for omp_alloc Allocator$$
34 
35 $head Deprecated 2011-08-31$$
36 Use the functions $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$
37 and $cref/thread_alloc:num_threads/ta_num_threads/$$ instead.
38 
39 $head Syntax$$
40 $codei%# include <cppad/utility/omp_alloc.hpp>
41 %$$
42 $codei%omp_alloc::set_max_num_threads(%number%)
43 %$$
44 $icode%number% = omp_alloc::get_max_num_threads()
45 %$$
46 
47 $head Purpose$$
48 By default there is only one thread and all execution is in sequential mode
49 (not $cref/parallel/omp_in_parallel/$$).
50 
51 $head number$$
52 The argument and return value $icode number$$ has prototype
53 $codei%
54 	size_t %number%
55 %$$
56 and must be greater than zero.
57 
58 $head set_max_num_threads$$
59 Informs $cref omp_alloc$$ of the maximum number of OpenMP threads.
60 
61 $head get_max_num_threads$$
62 Returns the valued used in the previous call to $code set_max_num_threads$$.
63 If there was no such previous call, the value one is returned
64 (and only thread number zero can use $cref omp_alloc$$).
65 
66 $head Restrictions$$
67 The function $code set_max_num_threads$$ must be called before
68 the program enters $cref/parallel/omp_in_parallel/$$ execution mode.
69 In addition, this function cannot be called while in parallel mode.
70 
71 $end
72 */
73 	/*!
74 	Inform omp_alloc of the maximum number of OpenMP threads and enable
75 	parallel execution mode by initializing all statics in this file.
76 
77 	\param number [in]
78 	maximum number of OpenMP threads.
79 	*/
set_max_num_threads(size_t number)80 	static void set_max_num_threads(size_t number)
81 	{	thread_alloc::parallel_setup(
82 			number, omp_alloc::in_parallel, omp_alloc::get_thread_num
83 		);
84 		thread_alloc::hold_memory(number > 1);
85 	}
86 	/*!
87 	Get the current maximum number of OpenMP threads that omp_alloc can use.
88 
89 	\return
90 	maximum number of OpenMP threads.
91 	*/
get_max_num_threads(void)92 	static size_t get_max_num_threads(void)
93 	{	return thread_alloc::num_threads(); }
94 
95 /* -----------------------------------------------------------------------
96 $begin omp_in_parallel$$
97 
98 $section Is The Current Execution in OpenMP Parallel Mode$$
99 $mindex in_parallel$$
100 $spell
101 	cppad.hpp
102 	omp_alloc
103 	bool
104 $$
105 
106 $head Deprecated 2011-08-31$$
107 Use the function $cref/thread_alloc::in_parallel/ta_in_parallel/$$ instead.
108 
109 $head Syntax$$
110 $codei%# include <cppad/utility/omp_alloc.hpp>
111 %$$
112 $icode%flag% = omp_alloc::in_parallel()%$$
113 
114 $head Purpose$$
115 Some of the $cref omp_alloc$$ allocation routines have different
116 specifications for parallel (not sequential) execution mode.
117 This routine enables you to determine if the current execution mode
118 is sequential or parallel.
119 
120 $head flag$$
121 The return value has prototype
122 $codei%
123 	bool %flag%
124 %$$
125 It is true if the current execution is in parallel mode
126 (possibly multi-threaded) and false otherwise (sequential mode).
127 
128 $head Example$$
129 $cref omp_alloc.cpp$$
130 
131 $end
132 */
133 	/// Are we in a parallel execution state; i.e., is it possible that
134 	/// other threads are currently executing.
in_parallel(void)135 	static bool in_parallel(void)
136 	{
137 # ifdef _OPENMP
138 		return omp_in_parallel() != 0;
139 # else
140 		return false;
141 # endif
142 	}
143 
144 /* -----------------------------------------------------------------------
145 $begin omp_get_thread_num$$
146 $spell
147 	cppad.hpp
148 	CppAD
149 	num
150 	omp_alloc
151 	cppad.hpp
152 $$
153 
154 $section Get the Current OpenMP Thread Number$$
155 $mindex get_thread_num$$
156 
157 $head Deprecated 2011-08-31$$
158 Use the function $cref/thread_alloc::thread_num/ta_thread_num/$$ instead.
159 
160 $head Syntax$$
161 $codei%# include <cppad/utility/omp_alloc.hpp>
162 %$$
163 $icode%thread% = omp_alloc::get_thread_num()%$$
164 
165 $head Purpose$$
166 Some of the $cref omp_alloc$$ allocation routines have a thread number.
167 This routine enables you to determine the current thread.
168 
169 $head thread$$
170 The return value $icode thread$$ has prototype
171 $codei%
172 	size_t %thread%
173 %$$
174 and is the currently executing thread number.
175 If $code _OPENMP$$ is not defined, $icode thread$$ is zero.
176 
177 $head Example$$
178 $cref omp_alloc.cpp$$
179 
180 $end
181 */
182 	/// Get current OpenMP thread number (zero if _OpenMP not defined).
get_thread_num(void)183 	static size_t get_thread_num(void)
184 	{
185 # ifdef _OPENMP
186 		size_t thread = static_cast<size_t>( omp_get_thread_num() );
187 		return thread;
188 # else
189 		return 0;
190 # endif
191 	}
192 /* -----------------------------------------------------------------------
193 $begin omp_get_memory$$
194 $spell
195 	cppad.hpp
196 	num
197 	ptr
198 	omp_alloc
199 $$
200 
201 $section Get At Least A Specified Amount of Memory$$
202 
203 $head Deprecated 2011-08-31$$
204 Use the function $cref/thread_alloc::get_memory/ta_get_memory/$$ instead.
205 
206 $head Syntax$$
207 $codei%# include <cppad/utility/omp_alloc.hpp>
208 %$$
209 $icode%v_ptr% = omp_alloc::get_memory(%min_bytes%, %cap_bytes%)%$$
210 
211 $head Purpose$$
212 Use $cref omp_alloc$$ to obtain a minimum number of bytes of memory
213 (for use by the $cref/current thread/omp_get_thread_num/$$).
214 
215 $head min_bytes$$
216 This argument has prototype
217 $codei%
218 	size_t %min_bytes%
219 %$$
220 It specifies the minimum number of bytes to allocate.
221 
222 $head cap_bytes$$
223 This argument has prototype
224 $codei%
225 	size_t& %cap_bytes%
226 %$$
227 It's input value does not matter.
228 Upon return, it is the actual number of bytes (capacity)
229 that have been allocated for use,
230 $codei%
231 	%min_bytes% <= %cap_bytes%
232 %$$
233 
234 $head v_ptr$$
235 The return value $icode v_ptr$$ has prototype
236 $codei%
237 	void* %v_ptr%
238 %$$
239 It is the location where the $icode cap_bytes$$ of memory
240 that have been allocated for use begins.
241 
242 $head Allocation Speed$$
243 This allocation should be faster if the following conditions hold:
244 $list number$$
245 The memory allocated by a previous call to $code get_memory$$
246 is currently available for use.
247 $lnext
248 The current $icode min_bytes$$ is between
249 the previous $icode min_bytes$$ and previous $icode cap_bytes$$.
250 $lend
251 
252 $head Example$$
253 $cref omp_alloc.cpp$$
254 
255 $end
256 */
257 	/*!
258 	Use omp_alloc to get a specified amount of memory.
259 
260 	If the memory allocated by a previous call to \c get_memory is now
261 	avaialable, and \c min_bytes is between its previous value
262 	and the previous \c cap_bytes, this memory allocation will have
263 	optimal speed. Otherwise, the memory allocation is more complicated and
264 	may have to wait for other threads to complete an allocation.
265 
266 	\param min_bytes [in]
267 	The minimum number of bytes of memory to be obtained for use.
268 
269 	\param cap_bytes [out]
270 	The actual number of bytes of memory obtained for use.
271 
272 	\return
273 	pointer to the beginning of the memory allocted for use.
274 	*/
get_memory(size_t min_bytes,size_t & cap_bytes)275 	static void* get_memory(size_t min_bytes, size_t& cap_bytes)
276 	{	return thread_alloc::get_memory(min_bytes, cap_bytes); }
277 
278 /* -----------------------------------------------------------------------
279 $begin omp_return_memory$$
280 $spell
281 	cppad.hpp
282 	ptr
283 	omp_alloc
284 $$
285 
286 $section Return Memory to omp_alloc$$
287 $mindex return_memory$$
288 
289 $head Deprecated 2011-08-31$$
290 Use the function $cref/thread_alloc::return_memory/ta_return_memory/$$ instead.
291 
292 $head Syntax$$
293 $codei%# include <cppad/utility/omp_alloc.hpp>
294 %$$
295 $codei%omp_alloc::return_memory(%v_ptr%)%$$
296 
297 $head Purpose$$
298 If $cref omp_max_num_threads$$ is one,
299 the memory is returned to the system.
300 Otherwise, the memory is retained by $cref omp_alloc$$ for quick future use
301 by the thread that allocated to memory.
302 
303 $head v_ptr$$
304 This argument has prototype
305 $codei%
306 	void* %v_ptr%
307 %$$.
308 It must be a pointer to memory that is currently in use; i.e.
309 obtained by a previous call to $cref omp_get_memory$$ and not yet returned.
310 
311 $head Thread$$
312 Either the $cref/current thread/omp_get_thread_num/$$ must be the same as during
313 the corresponding call to $cref omp_get_memory$$,
314 or the current execution mode must be sequential
315 (not $cref/parallel/omp_in_parallel/$$).
316 
317 $head NDEBUG$$
318 If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster).
319 Otherwise, a list of in use pointers is searched to make sure
320 that $icode v_ptr$$ is in the list.
321 
322 $head Example$$
323 $cref omp_alloc.cpp$$
324 
325 $end
326 */
327 	/*!
328 	Return memory that was obtained by \c get_memory.
329 	If  <code>max_num_threads(0) == 1</code>,
330 	the memory is returned to the system.
331 	Otherwise, it is retained by \c omp_alloc and available for use by
332 	\c get_memory for this thread.
333 
334 	\param v_ptr [in]
335 	Value of the pointer returned by \c get_memory and still in use.
336 	After this call, this pointer will available (and not in use).
337 
338 	\par
339 	We must either be in sequential (not parallel) execution mode,
340 	or the current thread must be the same as for the corresponding call
341 	to \c get_memory.
342 	*/
return_memory(void * v_ptr)343 	static void return_memory(void* v_ptr)
344 	{	thread_alloc::return_memory(v_ptr); }
345 /* -----------------------------------------------------------------------
346 $begin omp_free_available$$
347 $spell
348 	cppad.hpp
349 	omp_alloc
350 $$
351 
352 $section Free Memory Currently Available for Quick Use by a Thread$$
353 $mindex free_available$$
354 
355 $head Deprecated 2011-08-31$$
356 Use the function $cref/thread_alloc::free_available/ta_free_available/$$
357 instead.
358 
359 $head Syntax$$
360 $codei%# include <cppad/utility/omp_alloc.hpp>
361 %$$
362 $codei%omp_alloc::free_available(%thread%)%$$
363 
364 $head Purpose$$
365 Free memory, currently available for quick use by a specific thread,
366 for general future use.
367 
368 $head thread$$
369 This argument has prototype
370 $codei%
371 	size_t %thread%
372 %$$
373 Either $cref omp_get_thread_num$$ must be the same as $icode thread$$,
374 or the current execution mode must be sequential
375 (not $cref/parallel/omp_in_parallel/$$).
376 
377 $head Example$$
378 $cref omp_alloc.cpp$$
379 
380 $end
381 */
382 	/*!
383 	Return all the memory being held as available for a thread to the system.
384 
385 	\param thread [in]
386 	this thread that will no longer have any available memory after this call.
387 	This must either be the thread currently executing, or we must be
388 	in sequential (not parallel) execution mode.
389 	*/
free_available(size_t thread)390 	static void free_available(size_t thread)
391 	{	thread_alloc::free_available(thread); }
392 /* -----------------------------------------------------------------------
393 $begin omp_inuse$$
394 $spell
395 	cppad.hpp
396 	num
397 	inuse
398 	omp_alloc
399 $$
400 
401 $section Amount of Memory a Thread is Currently Using$$
402 $mindex inuse$$
403 
404 $head Deprecated 2011-08-31$$
405 
406 $head Syntax$$
407 $codei%# include <cppad/utility/omp_alloc.hpp>
408 %$$
409 $icode%num_bytes% = omp_alloc::inuse(%thread%)%$$
410 Use the function $cref/thread_alloc::inuse/ta_inuse/$$ instead.
411 
412 $head Purpose$$
413 Memory being managed by $cref omp_alloc$$ has two states,
414 currently in use by the specified thread,
415 and quickly available for future use by the specified thread.
416 This function informs the program how much memory is in use.
417 
418 $head thread$$
419 This argument has prototype
420 $codei%
421 	size_t %thread%
422 %$$
423 Either $cref omp_get_thread_num$$ must be the same as $icode thread$$,
424 or the current execution mode must be sequential
425 (not $cref/parallel/omp_in_parallel/$$).
426 
427 $head num_bytes$$
428 The return value has prototype
429 $codei%
430 	size_t %num_bytes%
431 %$$
432 It is the number of bytes currently in use by the specified thread.
433 
434 $head Example$$
435 $cref omp_alloc.cpp$$
436 
437 $end
438 */
439 	/*!
440 	Determine the amount of memory that is currently inuse.
441 
442 	\param thread [in]
443 	Thread for which we are determining the amount of memory
444 	(must be < CPPAD_MAX_NUM_THREADS).
445 	Durring parallel execution, this must be the thread
446 	that is currently executing.
447 
448 	\return
449 	The amount of memory in bytes.
450 	*/
inuse(size_t thread)451 	static size_t inuse(size_t thread)
452 	{	return thread_alloc::inuse(thread); }
453 /* -----------------------------------------------------------------------
454 $begin omp_available$$
455 $spell
456 	cppad.hpp
457 	num
458 	omp_alloc
459 $$
460 
461 $section Amount of Memory Available for Quick Use by a Thread$$
462 
463 $head Deprecated 2011-08-31$$
464 Use the function $cref/thread_alloc::available/ta_available/$$ instead.
465 
466 $head Syntax$$
467 $codei%# include <cppad/utility/omp_alloc.hpp>
468 %$$
469 $icode%num_bytes% = omp_alloc::available(%thread%)%$$
470 
471 $head Purpose$$
472 Memory being managed by $cref omp_alloc$$ has two states,
473 currently in use by the specified thread,
474 and quickly available for future use by the specified thread.
475 This function informs the program how much memory is available.
476 
477 $head thread$$
478 This argument has prototype
479 $codei%
480 	size_t %thread%
481 %$$
482 Either $cref omp_get_thread_num$$ must be the same as $icode thread$$,
483 or the current execution mode must be sequential
484 (not $cref/parallel/omp_in_parallel/$$).
485 
486 $head num_bytes$$
487 The return value has prototype
488 $codei%
489 	size_t %num_bytes%
490 %$$
491 It is the number of bytes currently available for use by the specified thread.
492 
493 $head Example$$
494 $cref omp_alloc.cpp$$
495 
496 $end
497 */
498 	/*!
499 	Determine the amount of memory that is currently available for use.
500 
501 	\copydetails inuse
502 	*/
available(size_t thread)503 	static size_t available(size_t thread)
504 	{	return thread_alloc::available(thread); }
505 /* -----------------------------------------------------------------------
506 $begin omp_create_array$$
507 $spell
508 	cppad.hpp
509 	omp_alloc
510 	sizeof
511 $$
512 
513 $section Allocate Memory and Create A Raw Array$$
514 $mindex create_array$$
515 
516 $head Deprecated 2011-08-31$$
517 Use the function $cref/thread_alloc::create_array/ta_create_array/$$ instead.
518 
519 $head Syntax$$
520 $codei%# include <cppad/utility/omp_alloc.hpp>
521 %$$
522 $icode%array% = omp_alloc::create_array<%Type%>(%size_min%, %size_out%)%$$.
523 
524 $head Purpose$$
525 Create a new raw array using $cref omp_alloc$$ a fast memory allocator
526 that works well in a multi-threading OpenMP environment.
527 
528 $head Type$$
529 The type of the elements of the array.
530 
531 $head size_min$$
532 This argument has prototype
533 $codei%
534 	size_t %size_min%
535 %$$
536 This is the minimum number of elements that there can be
537 in the resulting $icode array$$.
538 
539 $head size_out$$
540 This argument has prototype
541 $codei%
542 	size_t& %size_out%
543 %$$
544 The input value of this argument does not matter.
545 Upon return, it is the actual number of elements
546 in $icode array$$
547 ($icode% size_min %<=% size_out%$$).
548 
549 $head array$$
550 The return value $icode array$$ has prototype
551 $codei%
552 	%Type%* %array%
553 %$$
554 It is array with $icode size_out$$ elements.
555 The default constructor for $icode Type$$ is used to initialize the
556 elements of $icode array$$.
557 Note that $cref omp_delete_array$$
558 should be used to destroy the array when it is no longer needed.
559 
560 $head Delta$$
561 The amount of memory $cref omp_inuse$$ by the current thread,
562 will increase $icode delta$$ where
563 $codei%
564 	sizeof(%Type%) * (%size_out% + 1) > %delta% >= sizeof(%Type%) * %size_out%
565 %$$
566 The $cref omp_available$$ memory will decrease by $icode delta$$,
567 (and the allocation will be faster)
568 if a previous allocation with $icode size_min$$ between its current value
569 and $icode size_out$$ is available.
570 
571 $head Example$$
572 $cref omp_alloc.cpp$$
573 
574 $end
575 */
576 	/*!
577 	Use omp_alloc to Create a Raw Array.
578 
579 	\tparam Type
580 	The type of the elements of the array.
581 
582 	\param size_min [in]
583 	The minimum number of elements in the array.
584 
585 	\param size_out [out]
586 	The actual number of elements in the array.
587 
588 	\return
589 	pointer to the first element of the array.
590 	The default constructor is used to initialize
591 	all the elements of the array.
592 
593 	\par
594 	The \c extra_ field, in the \c omp_alloc node before the return value,
595 	is set to size_out.
596 	*/
597 	template <class Type>
create_array(size_t size_min,size_t & size_out)598 	static Type* create_array(size_t size_min, size_t& size_out)
599 	{	return thread_alloc::create_array<Type>(size_min, size_out); }
600 /* -----------------------------------------------------------------------
601 $begin omp_delete_array$$
602 $spell
603 	cppad.hpp
604 	omp_alloc
605 	sizeof
606 $$
607 
608 $section Return A Raw Array to The Available Memory for a Thread$$
609 $mindex delete_array$$
610 
611 $head Deprecated 2011-08-31$$
612 Use the function $cref/thread_alloc::delete_array/ta_delete_array/$$ instead.
613 
614 $head Syntax$$
615 $codei%# include <cppad/utility/omp_alloc.hpp>
616 %$$
617 $codei%omp_alloc::delete_array(%array%)%$$.
618 
619 $head Purpose$$
620 Returns memory corresponding to a raw array
621 (create by $cref omp_create_array$$) to the
622 $cref omp_available$$ memory pool for the current thread.
623 
624 $head Type$$
625 The type of the elements of the array.
626 
627 $head array$$
628 The argument $icode array$$ has prototype
629 $codei%
630 	%Type%* %array%
631 %$$
632 It is a value returned by $cref omp_create_array$$ and not yet deleted.
633 The $icode Type$$ destructor is called for each element in the array.
634 
635 $head Thread$$
636 The $cref/current thread/omp_get_thread_num/$$ must be the
637 same as when $cref omp_create_array$$ returned the value $icode array$$.
638 There is an exception to this rule:
639 when the current execution mode is sequential
640 (not $cref/parallel/omp_in_parallel/$$) the current thread number does not matter.
641 
642 $head Delta$$
643 The amount of memory $cref omp_inuse$$ will decrease by $icode delta$$,
644 and the $cref omp_available$$ memory will increase by $icode delta$$,
645 where $cref/delta/omp_create_array/Delta/$$
646 is the same as for the corresponding call to $code create_array$$.
647 
648 $head Example$$
649 $cref omp_alloc.cpp$$
650 
651 $end
652 */
653 	/*!
654 	Return Memory Used for a Raw Array to the Available Pool.
655 
656 	\tparam Type
657 	The type of the elements of the array.
658 
659 	\param array [in]
660 	A value returned by \c create_array that has not yet been deleted.
661 	The \c Type destructor is used to destroy each of the elements
662 	of the array.
663 
664 	\par
665 	Durring parallel execution, the current thread must be the same
666 	as during the corresponding call to \c create_array.
667 	*/
668 	template <class Type>
delete_array(Type * array)669 	static void delete_array(Type* array)
670 	{	thread_alloc::delete_array(array); }
671 };
672 /* --------------------------------------------------------------------------
673 $begin omp_efficient$$
674 $spell
675 	cppad.hpp
676 	omp_alloc
677 	ptr
678 	num
679 	bool
680 	const
681 $$
682 
683 $section Check If A Memory Allocation is Efficient for Another Use$$
684 
685 $head Removed$$
686 This function has been removed because speed tests seem to indicate
687 it is just as fast, or faster, to free and then reallocate the memory.
688 
689 $head Syntax$$
690 $codei%# include <cppad/utility/omp_alloc.hpp>
691 %$$
692 $icode%flag% = omp_alloc::efficient(%v_ptr%, %num_bytes%)%$$
693 
694 $head Purpose$$
695 Check if memory that is currently in use is an efficient
696 allocation for a specified number of bytes.
697 
698 $head v_ptr$$
699 This argument has prototype
700 $codei%
701 	const void* %v_ptr%
702 %$$.
703 It must be a pointer to memory that is currently in use; i.e.
704 obtained by a previous call to $cref omp_get_memory$$ and not yet returned.
705 
706 $head num_bytes$$
707 This argument has prototype
708 $codei%
709 	size_t %num_bytes%
710 %$$
711 It specifies the number of bytes of the memory allocated by $icode v_ptr$$
712 that we want to use.
713 
714 $head flag$$
715 The return value has prototype
716 $codei%
717 	bool %flag%
718 %$$
719 It is true,
720 a call to $code get_memory$$ with
721 $cref/min_bytes/omp_get_memory/min_bytes/$$
722 equal to $icode num_bytes$$ would result in a value for
723 $cref/cap_bytes/omp_get_memory/cap_bytes/$$ that is the same as when $code v_ptr$$
724 was returned by $code get_memory$$; i.e.,
725 $icode v_ptr$$ is an efficient memory block for $icode num_bytes$$
726 bytes of information.
727 
728 $head Thread$$
729 Either the $cref/current thread/omp_get_thread_num/$$ must be the same as during
730 the corresponding call to $cref omp_get_memory$$,
731 or the current execution mode must be sequential
732 (not $cref/parallel/omp_in_parallel/$$).
733 
734 $head NDEBUG$$
735 If $code NDEBUG$$ is defined, $icode v_ptr$$ is not checked (this is faster).
736 Otherwise, a list of in use pointers is searched to make sure
737 that $icode v_ptr$$ is in the list.
738 
739 $end
740 ---------------------------------------------------------------------------
741 $begin old_max_num_threads$$
742 $spell
743 	cppad.hpp
744 	inv
745 	CppAD
746 	num
747 	omp_alloc
748 $$
749 $section Set Maximum Number of Threads for omp_alloc Allocator$$
750 $mindex max_num_threads$$
751 
752 $head Removed$$
753 This function has been removed from the CppAD API.
754 Use the function $cref/thread_alloc::parallel_setup/ta_parallel_setup/$$
755 in its place.
756 
757 $head Syntax$$
758 $codei%# include <cppad/utility/omp_alloc.hpp>
759 %$$
760 $codei%omp_alloc::max_num_threads(%number%)%$$
761 
762 $head Purpose$$
763 By default there is only one thread and all execution is in sequential mode
764 (not $cref/parallel/omp_in_parallel/$$).
765 
766 $head number$$
767 The argument $icode number$$ has prototype
768 $codei%
769 	size_t %number%
770 %$$
771 It must be greater than zero and specifies the maximum number of
772 OpenMP threads that will be active at one time.
773 
774 $head Restrictions$$
775 This function must be called before the program enters
776 $cref/parallel/omp_in_parallel/$$ execution mode.
777 
778 $end
779 -------------------------------------------------------------------------------
780 */
781 } // END_CPPAD_NAMESPACE
782 
783 # endif
784