On Linux systems that didn't have PTHREAD_AFFINITY_NP, the compilation failed as the '#include'd ../../affinity.c and the config/linux/affinity.c then both defined the same NUMA functions.
Solved by moving them into a separate file (numa.c, config/linux/numa.c). Committed as r17-1794-g8ce473f8a26142 and sorry for the breakage! Tobias
commit 8ce473f8a26142a39487a0adac10570761f8ed90 Author: Tobias Burnus <[email protected]> Date: Wed Jun 24 07:15:04 2026 +0200 libgomp: Move internal NUMA function to a separate file [PR125940] At the previous location (affinity.c), the real and the fallback implementation of the NUMA functions were both in that file when HAVE_PTHREAD_AFFINITY_NP was unset. Solved by moving the internal NUMA functions into a separate file. Follow up to commit r17-1702-g8af1592882509f. libgomp/ChangeLog: PR libgomp/125940 * Makefile.am (libgomp_la_SOURCES): Add numa.c. * Makefile.in: Regenerate. * affinity.c (gomp_get_current_numa_node, gomp_get_numa_distance): Move to ... * numa.c: ... this new file. * config/linux/affinity.c (gomp_get_current_numa_node, gomp_get_numa_distance): Move to ... * config/linux/numa.c: ... this new file. --- libgomp/Makefile.am | 11 +++-- libgomp/Makefile.in | 17 +++---- libgomp/affinity.c | 14 ------ libgomp/config/linux/affinity.c | 68 -------------------------- libgomp/config/linux/numa.c | 104 ++++++++++++++++++++++++++++++++++++++++ libgomp/numa.c | 40 ++++++++++++++++ 6 files changed, 159 insertions(+), 95 deletions(-) diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am index 0902164b500..de9cad6c7d3 100644 --- a/libgomp/Makefile.am +++ b/libgomp/Makefile.am @@ -66,11 +66,12 @@ libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c error.c \ icv.c icv-device.c iter.c iter_ull.c loop.c loop_ull.c ordered.c \ parallel.c scope.c sections.c single.c task.c team.c work.c lock.c \ - mutex.c proc.c sem.c bar.c ptrlock.c time.c fortran.c affinity.c \ - target.c splay-tree.c libgomp-plugin.c oacc-parallel.c oacc-host.c \ - oacc-init.c oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c \ - priority_queue.c affinity-fmt.c teams.c allocator.c simple-allocator.c \ - oacc-profiling.c oacc-target.c target-indirect.c target-cxa-dso-dtor.c + mutex.c numa.c proc.c sem.c bar.c ptrlock.c time.c fortran.c \ + affinity.c target.c splay-tree.c libgomp-plugin.c oacc-parallel.c \ + oacc-host.c oacc-init.c oacc-mem.c oacc-async.c oacc-plugin.c \ + oacc-cuda.c priority_queue.c affinity-fmt.c teams.c allocator.c \ + simple-allocator.c oacc-profiling.c oacc-target.c target-indirect.c \ + target-cxa-dso-dtor.c include $(top_srcdir)/plugin/Makefrag.am diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in index 19ed6e8283c..61fb775d91f 100644 --- a/libgomp/Makefile.in +++ b/libgomp/Makefile.in @@ -219,7 +219,7 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo critical.lo \ env.lo error.lo icv.lo icv-device.lo iter.lo iter_ull.lo \ loop.lo loop_ull.lo ordered.lo parallel.lo scope.lo \ sections.lo single.lo task.lo team.lo work.lo lock.lo mutex.lo \ - proc.lo sem.lo bar.lo ptrlock.lo time.lo fortran.lo \ + numa.lo proc.lo sem.lo bar.lo ptrlock.lo time.lo fortran.lo \ affinity.lo target.lo splay-tree.lo libgomp-plugin.lo \ oacc-parallel.lo oacc-host.lo oacc-init.lo oacc-mem.lo \ oacc-async.lo oacc-plugin.lo oacc-cuda.lo priority_queue.lo \ @@ -554,13 +554,13 @@ libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c \ error.c icv.c icv-device.c iter.c iter_ull.c loop.c loop_ull.c \ ordered.c parallel.c scope.c sections.c single.c task.c team.c \ - work.c lock.c mutex.c proc.c sem.c bar.c ptrlock.c time.c \ - fortran.c affinity.c target.c splay-tree.c libgomp-plugin.c \ - oacc-parallel.c oacc-host.c oacc-init.c oacc-mem.c \ - oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \ - affinity-fmt.c teams.c allocator.c simple-allocator.c \ - oacc-profiling.c oacc-target.c target-indirect.c \ - target-cxa-dso-dtor.c $(am__append_3) + work.c lock.c mutex.c numa.c proc.c sem.c bar.c ptrlock.c \ + time.c fortran.c affinity.c target.c splay-tree.c \ + libgomp-plugin.c oacc-parallel.c oacc-host.c oacc-init.c \ + oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c \ + priority_queue.c affinity-fmt.c teams.c allocator.c \ + simple-allocator.c oacc-profiling.c oacc-target.c \ + target-indirect.c target-cxa-dso-dtor.c $(am__append_3) # Nvidia PTX OpenACC plugin. @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION) @@ -771,6 +771,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_ull.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mutex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/numa.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-async.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-cuda.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-host.Plo@am__quote@ diff --git a/libgomp/affinity.c b/libgomp/affinity.c index 060fefbe540..a194ba97ba3 100644 --- a/libgomp/affinity.c +++ b/libgomp/affinity.c @@ -152,19 +152,5 @@ gomp_display_affinity_place (char *buffer, size_t size, size_t *ret, gomp_display_string (buffer, size, ret, buf, strlen (buf)); } -int -gomp_get_current_numa_node () -{ - return -1; -} - -int -gomp_get_numa_distance (int node1, int node2) -{ - (void) node1; - (void) node2; - return -1; -} - ialias(omp_get_place_num_procs) ialias(omp_get_place_proc_ids) diff --git a/libgomp/config/linux/affinity.c b/libgomp/config/linux/affinity.c index ca14be9690e..d30187b6064 100644 --- a/libgomp/config/linux/affinity.c +++ b/libgomp/config/linux/affinity.c @@ -30,14 +30,12 @@ #endif #include "libgomp.h" #include "proc.h" -#include <dirent.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <limits.h> -#include <sys/syscall.h> #ifdef HAVE_PTHREAD_AFFINITY_NP @@ -626,69 +624,3 @@ ialias(omp_get_place_proc_ids) #include "../../affinity.c" #endif - -static int num_numa_nodes = 0; -static int *numa_distances = NULL; - -int -gomp_get_current_numa_node () -{ - int node; - syscall (SYS_getcpu, NULL /* cpu */, &node, NULL /* no longer used */); - return node; -} - -int -gomp_get_numa_distance (int node1, int node2) -{ - if (node1 < 0 || node2 < 0 || num_numa_nodes < 0) - return -1; - - if (numa_distances == NULL) - { - num_numa_nodes = -1; - DIR *dir = opendir ("/sys/devices/system/node"); - if (!dir) - return -1; - struct dirent *dp; - int cnt = 0; - errno = 0; - while ((dp = readdir(dir)) != NULL) - if (strncmp ("node", dp->d_name, 4 /* strlen ("node") */) == 0) - cnt++; - else if (errno) - { - closedir (dir); - return -1; - } - closedir (dir); - numa_distances = (int *) gomp_malloc (sizeof (int) * cnt * cnt); - - constexpr int len = sizeof ("/sys/devices/system/node/node12345/" - "distance"); - char filename[len]; - - for (int i = 0; i < cnt; i++) - { - if (len < snprintf (filename, sizeof (filename), - "/sys/devices/system/node/node%d/distance", i)) - return -1; - int distance = -1; - FILE *in = fopen (filename, "r"); - for (int j = 0; j < cnt; j++) - { - fscanf (in, "%d", &distance); - if (distance == -1) - { - fclose (in); - free (numa_distances); - return -1; - } - numa_distances[i * cnt + j] = distance; - } - fclose (in); - } - num_numa_nodes = cnt; - } - return numa_distances[node1 * num_numa_nodes + node2]; -} diff --git a/libgomp/config/linux/numa.c b/libgomp/config/linux/numa.c new file mode 100644 index 00000000000..d43b34b98dd --- /dev/null +++ b/libgomp/config/linux/numa.c @@ -0,0 +1,104 @@ +/* Copyright (C) 2026 Free Software Foundation, Inc. + Contributed by Tobias Burnus <[email protected]> + + This file is part of the GNU Offloading and Multi Processing Library + (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* Linux specific version of internally used NUMA information routines. */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif +#include "libgomp.h" +#include <dirent.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/syscall.h> + + +static int num_numa_nodes = 0; +static int *numa_distances = NULL; + +int +gomp_get_current_numa_node () +{ + int node; + syscall (SYS_getcpu, NULL /* cpu */, &node, NULL /* no longer used */); + return node; +} + +int +gomp_get_numa_distance (int node1, int node2) +{ + if (node1 < 0 || node2 < 0 || num_numa_nodes < 0) + return -1; + + if (numa_distances == NULL) + { + num_numa_nodes = -1; + DIR *dir = opendir ("/sys/devices/system/node"); + if (!dir) + return -1; + struct dirent *dp; + int cnt = 0; + errno = 0; + while ((dp = readdir(dir)) != NULL) + if (strncmp ("node", dp->d_name, 4 /* strlen ("node") */) == 0) + cnt++; + else if (errno) + { + closedir (dir); + return -1; + } + closedir (dir); + numa_distances = (int *) gomp_malloc (sizeof (int) * cnt * cnt); + + constexpr int len = sizeof ("/sys/devices/system/node/node12345/" + "distance"); + char filename[len]; + + for (int i = 0; i < cnt; i++) + { + if (len < snprintf (filename, sizeof (filename), + "/sys/devices/system/node/node%d/distance", i)) + return -1; + int distance = -1; + FILE *in = fopen (filename, "r"); + for (int j = 0; j < cnt; j++) + { + fscanf (in, "%d", &distance); + if (distance == -1) + { + fclose (in); + free (numa_distances); + return -1; + } + numa_distances[i * cnt + j] = distance; + } + fclose (in); + } + num_numa_nodes = cnt; + } + return numa_distances[node1 * num_numa_nodes + node2]; +} diff --git a/libgomp/numa.c b/libgomp/numa.c new file mode 100644 index 00000000000..37d790d18bc --- /dev/null +++ b/libgomp/numa.c @@ -0,0 +1,40 @@ +/* Copyright (C) 2026 Free Software Foundation, Inc. + Contributed by Tobias Burnus <[email protected]> + + This file is part of the GNU Offloading and Multi Processing Library + (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* Stub version of internally used NUMA information routines. */ + +int +gomp_get_current_numa_node () +{ + return -1; +} + +int +gomp_get_numa_distance (int node1, int node2) +{ + (void) node1; + (void) node2; + return -1; +}
