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