src/Pure/System/numa.scala
author wenzelm
Wed, 01 Mar 2023 13:30:35 +0100
changeset 77438 0030eabbe6c3
parent 77329 1b7c5d4b97a8
permissions -rw-r--r--
more robust: synchronized access to database;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/System/numa.scala
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     3
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     4
Support for Non-Uniform Memory Access of separate CPU nodes.
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     5
*/
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     6
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     7
package isabelle
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     8
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
     9
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 71601
diff changeset
    10
object NUMA {
77329
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    11
  /* information about nodes */
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    12
77329
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    13
  private val numa_info_linux: Path = Path.explode("/sys/devices/system/node/online")
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    14
77329
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    15
  private val Info_Single = """^(\d+)$""".r
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    16
  private val Info_Multiple = """^(\d+)-(\d+)$""".r
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    17
77329
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    18
  private def parse_nodes(s: String): List[Int] =
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    19
    s match {
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    20
      case Info_Single(Value.Int(i)) => List(i)
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    21
      case Info_Multiple(Value.Int(i), Value.Int(j)) => (i to j).toList
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    22
      case _ => error("Cannot parse CPU node specification: " + quote(s))
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    23
    }
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    24
77329
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    25
  def nodes(enabled: Boolean = true, ssh: SSH.System = SSH.Local): List[Int] = {
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    26
    val numa_info = if (ssh.isabelle_platform.is_linux) Some(numa_info_linux) else None
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    27
    for {
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    28
      path <- numa_info.toList
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    29
      if enabled && ssh.is_file(path)
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    30
      s <- space_explode(',', ssh.read(path).trim)
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    31
      n <- parse_nodes(s)
1b7c5d4b97a8 misc tuning and clarification;
wenzelm
parents: 77326
diff changeset
    32
    } yield n
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    33
  }
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    34
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    35
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    36
  /* CPU policy via numactl tool */
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    37
77319
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    38
  def numactl(node: Int): String = "numactl -m" + node + " -N" + node
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    39
  def numactl_ok(node: Int): Boolean = Isabelle_System.bash(numactl(node) + " true").ok
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    40
77319
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    41
  def policy(node: Int): String = if (numactl_ok(node)) numactl(node) else ""
64265
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    42
77318
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    43
  def policy_options(options: Options, numa_node: Option[Int]): Options =
68953
89a12af9c330 tuned signature;
wenzelm
parents: 66923
diff changeset
    44
    numa_node match {
89a12af9c330 tuned signature;
wenzelm
parents: 66923
diff changeset
    45
      case None => options
89a12af9c330 tuned signature;
wenzelm
parents: 66923
diff changeset
    46
      case Some(n) => options.string("ML_process_policy") = policy(n)
89a12af9c330 tuned signature;
wenzelm
parents: 66923
diff changeset
    47
    }
89a12af9c330 tuned signature;
wenzelm
parents: 66923
diff changeset
    48
77318
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    49
  def perhaps_policy_options(options: Options): Options = {
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    50
    val numa_node =
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    51
      try {
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    52
        nodes() match {
77319
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    53
          case ns if ns.length >= 2 && numactl_ok(ns.head) => Some(ns.head)
77318
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    54
          case _ => None
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    55
        }
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    56
      }
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    57
      catch { case ERROR(_) => None }
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    58
    policy_options(options, numa_node)
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    59
  }
7a03477bf3d5 clarified signature: more concise operations;
wenzelm
parents: 77317
diff changeset
    60
64265
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    61
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    62
  /* shuffling of CPU nodes */
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    63
77326
b3f8aad678e9 clarified signature;
wenzelm
parents: 77319
diff changeset
    64
  def check(progress: Progress, enabled: Boolean): Boolean = {
64265
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    65
    def warning =
77319
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    66
      nodes() match {
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    67
        case ns if ns.length < 2 => Some("no NUMA nodes available")
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    68
        case ns if !numactl_ok(ns.head) => Some("bad numactl tool")
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    69
        case _ => None
87698fe320bb clarified signature: more robust operations, without assumption about node 0;
wenzelm
parents: 77318
diff changeset
    70
      }
64265
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    71
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    72
    enabled &&
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    73
      (warning match {
65831
3b197547c1d4 prefer explicit progress channel;
wenzelm
parents: 64497
diff changeset
    74
        case Some(s) => progress.echo_warning("Shuffling of CPU nodes is disabled: " + s); false
64265
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    75
        case _ => true
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    76
      })
8eb6365f5916 isabelle build -N;
wenzelm
parents: 64264
diff changeset
    77
  }
64264
42138702d6ec support for Non-Uniform Memory Access of separate CPU nodes;
wenzelm
parents:
diff changeset
    78
}