This file is indexed.

/usr/share/sagemath/bin/sage-num-threads.py is in sagemath-common 7.4-9.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  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
182
#!/usr/bin/env python
#
# Determine the number of threads to be used by Sage.
#
# Outputs three space-separated numbers:
# 1) The number of threads to use for Sage, based on MAKE, MAKEFLAGS
#    and SAGE_NUM_THREADS
# 2) The number of threads to use when parallel execution is explicitly
#    asked for (e.g. sage -tp)
# 3) The number of CPU cores in the system, as determined by
#    multiprocessing.cpu_count()
#
# AUTHOR: Jeroen Demeyer (2011-12-08): Trac ticket #12016
#

from __future__ import print_function

import os
import multiprocessing
import re
import math

def number_of_cores():
    """
    Try to determine the number of CPU cores in this system.
    If successful return that number. Otherwise return 1.
    """
    # If the environment variable SAGE_NUM_CORES exists, use that value.
    # This is useful for testing purposes.
    try:
        n = int(os.environ["SAGE_NUM_CORES"])
        if n > 0:
            return n
    except (ValueError, KeyError):
        pass

    try:
        n = multiprocessing.cpu_count()
        if n > 0:
            return n
    except NotImplementedError:
        pass

    try:  # Solaris fix
        from subprocess import Popen, PIPE
        p = Popen(['sysctl','-n','hw.ncpu'], stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
        n = int(p.stdout.read().strip())
        if n > 0:
            return n
    except (ValueError, OSError):
        pass

    return 1

def parse_jobs_from_MAKE(MAKE, unlimited=999999):
    """
    Parse an environment variable like :envvar:`MAKE` for the number of
    jobs specified. This looks at arguments ``-j``, ``--jobs``, ``-l``,
    ``--load-average``.

    INPUT:

    - ``MAKE`` -- The value of :envvar:`MAKE` or :envvar:`MAKEFLAGS`.

    - ``unlimited`` -- The value to return when ``MAKE`` contains ``-j``
      without argument and no ``-l`` option.  Normally this is interpreted
      as "unlimited".

    OUTPUT:

    The number of jobs specified by that variable.  Raise ``KeyError``
    if no number of jobs is specified in ``MAKE``.
    """
    # First, find value of -j
    # Since this is doing a greedy match on the left and non-greedy on the right,
    # we find the last -j or --jobs
    (j,num) = re.subn(r'^(.* )?(-j *|--jobs(=(?=[0-9])| +))([0-9]*)( .*?)?$', r'\4', MAKE, count=1)
    if num < 1:
        # No replacement done, i.e. no -j option found
        raise KeyError("No number of jobs specified")
    elif j == "":
        # j is empty: unlimited number of jobs! :-)
        j = unlimited
    else:
        j = int(j)
        if j <= 0:
            raise ValueError("Non-positive value specified for -j")

    # Next, find the value of -l
    # If it is specified, use this as an upper bound on j
    (l,num) = re.subn(r'^(.* )?(-l *|--(load-average|max-load)(=(?=[0-9])| +))([0-9.]*)( .*?)?$', r'\5', MAKE, count=1)
    if num < 1:
        # No replacement done, i.e. no -l option found
        pass
    elif l == "":
        # No load limit specified
        pass
    else:
        l = int(math.ceil(float(l)))
        # A load limit will never prevent starting at least one job
        if l <= 1:
            l = 1
        j = min(j,l)

    return j

def num_threads():
    """
    Determine the number of threads from the environment variables
    (in decreasing priority) :envvar:`SAGE_NUM_THREADS`, :envvar:`MAKE`,
    :envvar:`MAKEFLAGS` and :envvar:`MFLAGS`.

    If :envvar:`SAGE_NUM_THREADS` is 0 and neither :envvar:`MAKE` nor
    :envvar:`MAKEFLAGS` specifies a number of jobs, the use a default
    of ``min(8, number_of_cores)``.

    OUTPUT:

    a tuple (num_threads, num_threads_parallel, num_cores)
    """
    num_cores = number_of_cores()

    num_threads = None
    # Handle MFLAGS only for backwards compatibility
    try:
        num_threads = parse_jobs_from_MAKE(os.environ["MFLAGS"], unlimited=2)
    except (ValueError, KeyError):
        pass

    try:
        # Prepend hyphen to MAKEFLAGS if it does not start with one
        MAKEFLAGS=os.environ["MAKEFLAGS"]
        if MAKEFLAGS[0] != '-':
            MAKEFLAGS = '-' + MAKEFLAGS
        # In MAKEFLAGS, "-j" does not mean unlimited.  It probably
        # means an inherited number of jobs, let us use 2 for safety.
        num_threads = parse_jobs_from_MAKE(MAKEFLAGS, unlimited=2)
    except (ValueError, KeyError, IndexError):
        pass

    try:
        num_threads = parse_jobs_from_MAKE(os.environ["MAKE"])
    except (ValueError, KeyError):
        pass

    # Number of threads to use when parallel execution is explicitly
    # asked for
    num_threads_parallel = num_threads
    if num_threads_parallel is None:
        num_threads_parallel = max(min(8, num_cores), 2)

    try:
        sage_num_threads = int(os.environ["SAGE_NUM_THREADS"])
        if sage_num_threads == 0:
            # If SAGE_NUM_THREADS is 0, use the default only
            # if none of the above variables specified anything.
            if num_threads is None:
                num_threads = min(8, num_cores)
        elif sage_num_threads > 0:
            # SAGE_NUM_THREADS overrides everything
            num_threads = sage_num_threads
            num_threads_parallel = sage_num_threads
    except (ValueError, KeyError):
        pass

    # If we still don't know, use 1 thread
    if num_threads is None:
        num_threads = 1

    # Finally, use SAGE_NUM_THREADS_PARALLEL if set.  A user isn't
    # likely to set this, but it ensures that sage-env is idempotent
    # if called more than once.
    try:
        sage_num_threads = int(os.environ["SAGE_NUM_THREADS_PARALLEL"])
        if sage_num_threads > 0:
            num_threads_parallel = sage_num_threads
    except (ValueError, KeyError):
        pass

    return (num_threads, num_threads_parallel, num_cores)

print(*num_threads())