1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2012-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 #  include "config.h"
28 #endif
29 
30 #include "nproc-wrapper.h"
31 
32 #include "defun.h"
33 #include "error.h"
34 
35 DEFUN (nproc, args, ,
36        doc: /* -*- texinfo -*-
37 @deftypefn  {} {} nproc ()
38 @deftypefnx {} {} nproc (@var{query})
39 Return the current number of available processors.
40 
41 If called with the optional argument @var{query}, modify how processors
42 are counted as follows:
43 
44 @table @code
45 @item all
46 total number of processors.
47 
48 @item current
49 processors available to the current process.
50 
51 @item overridable
52 same as @code{current}, but overridable through the
53 @w{@env{OMP_NUM_THREADS}} environment variable.
54 @end table
55 @end deftypefn */)
56 {
57   int nargin = args.length ();
58 
59   if (nargin > 1)
60     print_usage ();
61 
62   octave_nproc_query query = OCTAVE_NPROC_CURRENT_OVERRIDABLE;
63 
64   if (nargin == 1)
65     {
66       std::string arg = args(0).string_value ();
67 
68       std::transform (arg.begin (), arg.end (), arg.begin (), tolower);
69 
70       if (arg == "all")
71         query = OCTAVE_NPROC_ALL;
72       else if (arg == "current")
73         query = OCTAVE_NPROC_CURRENT;
74       else if (arg == "overridable")
75         query = OCTAVE_NPROC_CURRENT_OVERRIDABLE;
76       else
77         error ("nproc: invalid value for QUERY");
78     }
79 
80   return ovl (octave_num_processors_wrapper (query));
81 }
82 
83 /*
84 ## Must always report at least 1 cpu available
85 %!assert (nproc () >= 1)
86 %!assert (nproc ("all") >= 1)
87 %!assert (nproc ("current") >= 1)
88 
89 ## Test that "overridable" is the default
90 %!assert (nproc ("overridable"), nproc ())
91 
92 %!test
93 %! c = nproc ("current");
94 %! unwind_protect
95 %!   old_val = getenv ("OMP_NUM_THREADS");
96 %!   new_val = c + 1;
97 %!   setenv ("OMP_NUM_THREADS", num2str (new_val));
98 %!   assert (nproc ("overridable"), new_val);
99 %! unwind_protect_cleanup
100 %!   if (! isempty (old_val))
101 %!     setenv ("OMP_NUM_THREADS", old_val);
102 %!   else
103 %!     unsetenv ("OMP_NUM_THREADS");
104 %!   endif
105 %! end_unwind_protect
106 
107 %!error nproc ("no_valid_option")
108 */
109