You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/openmp-utils.c
+34-26Lines changed: 34 additions & 26 deletions
Original file line number
Diff line number
Diff line change
@@ -12,14 +12,14 @@ static bool RestoreAfterFork = true; // see #2885 in v1.12.0
12
12
staticintgetIntEnv(constchar*name, intdef)
13
13
{
14
14
constchar*val=getenv(name);
15
-
if (val==NULL) returndef;
15
+
if (val==NULL) returndef;
16
16
size_tnchar=strlen(val);
17
-
if (nchar==0) returndef;
17
+
if (nchar==0) returndef;
18
18
char*end;
19
19
errno=0;
20
20
long intans=strtol(val, &end, 10); // ignores leading whitespace. If it fully consumed the string, *end=='\0' and isspace('\0')==false
21
21
while (isspace(*end)) end++; // ignore trailing whitespace
22
-
if (errno|| (size_t)(end-val)!=nchar||ans<1||ans>INT_MAX) {
22
+
if (errno|| (size_t)(end-val)!=nchar||ans<1||ans>INT_MAX) {
23
23
warning(_("Ignoring invalid %s==\"%s\". Not an integer >= 1. Please remove any characters that are not a digit [0-9]. See ?data.table::setDTthreads."), name, val);
24
24
returndef;
25
25
}
@@ -29,23 +29,24 @@ static int getIntEnv(const char *name, int def)
29
29
staticinlineintimin(inta, intb) { returna<b ? a : b; }
30
30
staticinlineintimax(inta, intb) { returna>b ? a : b; }
31
31
32
-
voidinitDTthreads(void) {
32
+
voidinitDTthreads(void)
33
+
{
33
34
// called at package startup from init.c
34
35
// also called by setDTthreads(threads=NULL) (default) to reread environment variables; see setDTthreads below
35
36
// No verbosity here in this setter. Verbosity is in getDTthreads(verbose=TRUE)
ans=imin(ans, omp_get_num_procs()); // num_procs is a hard limit; user cannot achieve more. ifndef _OPENMP then myomp.h defines this to be 1
39
40
} else {
40
41
// Only when R_DATATABLE_NUM_THREADS is unset (or <=0) do we use PROCS_PERCENT; #4514
41
42
intperc=getIntEnv("R_DATATABLE_NUM_PROCS_PERCENT", 50); // use "NUM_PROCS" to use the same name as the OpenMP function this uses
42
43
// 50% of logical CPUs by default; half of 8 is 4 on laptop with 4 cores. Leaves plenty of room for other processes: #3395 & #3298
43
-
if (perc<=1||perc>100) {
44
+
if (perc <= 1||perc>100) {
44
45
warning(_("Ignoring invalid R_DATATABLE_NUM_PROCS_PERCENT==%d. If used it must be an integer between 2 and 100. Default is 50. See ?setDTtheads."), perc);
45
46
// not allowing 1 is to catch attempts to use 1 or 1.0 to represent 100%.
46
47
perc=50;
47
48
}
48
-
ans=imax(omp_get_num_procs()*perc/100, 1); // imax for when formula would result in 0.
49
+
ans=imax(omp_get_num_procs()*perc / 100, 1); // imax for when formula would result in 0.
49
50
}
50
51
ans=imin(ans, omp_get_thread_limit()); // honors OMP_THREAD_LIMIT when OpenMP started; e.g. CRAN sets this to 2. Often INT_MAX meaning unlimited/unset
51
52
ans=imin(ans, omp_get_max_threads()); // honors OMP_NUM_THREADS when OpenMP started, plus reflects any omp_set_* calls made since
@@ -57,24 +58,27 @@ void initDTthreads(void) {
57
58
DTthrottle=imax(1, getIntEnv("R_DATATABLE_THROTTLE", 1024)); // 2nd thread is used only when n>1024, 3rd thread when n>2048, etc
// If a CPU has been unplugged (high end servers allow live hardware replacement) then omp_get_num_procs() will
124
129
// reflect that and a call to setDTthreads(threads=NULL) will update DTthreads.
125
130
} elseif (length(threads)) {
126
-
intn=0;
127
-
if (length(threads)!=1|| !isInteger(threads) || (n=INTEGER(threads)[0]) <0) { // <0 catches NA too since NA is negative (INT_MIN)
131
+
intn=0;
132
+
if (length(threads)!=1|| !isInteger(threads) || (n=INTEGER(threads)[0]) <0) { // <0 catches NA too since NA is negative (INT_MIN)
128
133
error(_("threads= must be either NULL or a single number >= 0. See ?setDTthreads."));
129
134
}
130
135
intnum_procs=imax(omp_get_num_procs(), 1); // max just in case omp_get_num_procs() returns <= 0 (perhaps error, or unsupported)
131
-
if (!isLogical(percent) ||length(percent)!=1||LOGICAL(percent)[0]==NA_LOGICAL) {
136
+
if (!isLogical(percent) ||length(percent)!=1||LOGICAL(percent)[0]==NA_LOGICAL) {
132
137
internal_error(__func__, "percent= must be TRUE or FALSE at C level"); // # nocov
133
138
}
134
139
if (LOGICAL(percent)[0]) {
135
-
if (n<2||n>100) internal_error(__func__, "threads==%d should be between 2 and 100 (percent=TRUE at C level)", n); // # nocov
136
-
n=num_procs*n/100; // if 0 it will be reset to 1 in the imax() below
140
+
if (n<2||n>100) internal_error(__func__, "threads==%d should be between 2 and 100 (percent=TRUE at C level)", n); // # nocov
141
+
n=num_procs*n / 100; // if 0 it will be reset to 1 in the imax() below
137
142
} else {
138
-
if (n==0||n>num_procs) n=num_procs; // setDTthreads(0) == setDTthread(percent=100); i.e. use all logical CPUs (the default in 1.12.0 and before, from 1.12.2 it's 50%)
143
+
if (n==0||n>num_procs) n=num_procs; // setDTthreads(0) == setDTthread(percent=100); i.e. use all logical CPUs (the default in 1.12.0 and before, from 1.12.2 it's 50%)
139
144
}
140
145
n=imin(n, omp_get_thread_limit()); // can't think why this might be different from its value on startup, but call it just in case
141
146
n=imin(n, getIntEnv("OMP_THREAD_LIMIT", INT_MAX)); // user might have called Sys.setenv(OMP_THREAD_LIMIT=) since startup and expect setDTthreads to respect it
error(_("Attempting to substitute '%s' element with object of type '%s' but it has to be 'symbol' type when substituting name of the call argument, functions 'as.name' and 'I' can be used to work out proper substitution, see ?substitute2 examples."), CHAR(STRING_ELT(arg_names, i)), type2char(TYPEOF(sym)));
18
19
SET_TAG(tmp, sym);
19
20
}
20
21
UNPROTECT(1); // chmatch
21
22
}
22
-
for (SEXPtmp=expr; tmp!=R_NilValue; tmp=CDR(tmp)) { // recursive call to substitute in nested expressions
23
+
for (SEXPtmp=expr; tmp!=R_NilValue; tmp=CDR(tmp)) { // recursive call to substitute in nested expressions
0 commit comments