openmp: Add support for OMP_PLACES=numa_domains

This adds support for numa_domains abstract name in OMP_PLACES, also new
in OpenMP 5.1.

Way to test this is
OMP_PLACES=numa_domains OMP_DISPLAY_ENV=true LD_PRELOAD=.libs/libgomp.so.1 /bin/true
and see what it prints on OMP_PLACES line.
For non-NUMA machines it should print a single place that covers all CPUs,
for NUMA machine one place for each NUMA node with corresponding CPUs.

2021-10-15  Jakub Jelinek  <jakub@redhat.com>

	* env.c (parse_places_var): Handle numa_domains as level 5.
	* config/linux/affinity.c (gomp_affinity_init_numa_domains): New
	function.
	(gomp_affinity_init_level): Use it instead of
	gomp_affinity_init_level_1 for level == 5.
	* testsuite/libgomp.c/places-5.c: New test.
This commit is contained in:
Jakub Jelinek 2021-10-15 12:16:50 +02:00
parent 5809be05a2
commit e7ce32c783
3 changed files with 116 additions and 2 deletions

View File

@ -355,6 +355,102 @@ gomp_affinity_init_level_1 (int level, int this_level, unsigned long count,
free (line);
}
static void
gomp_affinity_init_numa_domains (unsigned long count, cpu_set_t *copy,
char *name)
{
FILE *f;
char *nline = NULL, *line = NULL;
size_t nlinelen = 0, linelen = 0;
char *q;
size_t prefix_len = sizeof ("/sys/devices/system/node/") - 1;
strcpy (name, "/sys/devices/system/node/online");
f = fopen (name, "r");
if (f == NULL || getline (&nline, &nlinelen, f) <= 0)
{
if (f)
fclose (f);
return;
}
fclose (f);
q = nline;
while (*q && *q != '\n' && gomp_places_list_len < count)
{
unsigned long nfirst, nlast;
errno = 0;
nfirst = strtoul (q, &q, 10);
if (errno)
break;
nlast = nfirst;
if (*q == '-')
{
errno = 0;
nlast = strtoul (q + 1, &q, 10);
if (errno || nlast < nfirst)
break;
}
for (; nfirst <= nlast; nfirst++)
{
sprintf (name + prefix_len, "node%lu/cpulist", nfirst);
f = fopen (name, "r");
if (f == NULL)
continue;
if (getline (&line, &linelen, f) > 0)
{
char *p = line;
void *pl = NULL;
while (*p && *p != '\n')
{
unsigned long first, last;
bool seen = false;
errno = 0;
first = strtoul (p, &p, 10);
if (errno)
break;
last = first;
if (*p == '-')
{
errno = 0;
last = strtoul (p + 1, &p, 10);
if (errno || last < first)
break;
}
for (; first <= last; first++)
{
if (!CPU_ISSET_S (first, gomp_cpuset_size, copy))
continue;
if (pl == NULL)
{
pl = gomp_places_list[gomp_places_list_len];
gomp_affinity_init_place (pl);
}
if (gomp_affinity_add_cpus (pl, first, 1, 0, true))
{
CPU_CLR_S (first, gomp_cpuset_size, copy);
if (!seen)
{
gomp_places_list_len++;
seen = true;
}
}
}
if (*p == ',')
++p;
}
}
fclose (f);
}
if (*q == ',')
++q;
}
free (line);
free (nline);
}
bool
gomp_affinity_init_level (int level, unsigned long count, bool quiet)
{
@ -377,8 +473,11 @@ gomp_affinity_init_level (int level, unsigned long count, bool quiet)
copy = gomp_alloca (gomp_cpuset_size);
strcpy (name, "/sys/devices/system/cpu/cpu");
memcpy (copy, gomp_cpusetp, gomp_cpuset_size);
gomp_affinity_init_level_1 (level, level > 3 ? level : 3, count, copy, name,
quiet);
if (level == 5)
gomp_affinity_init_numa_domains (count, copy, name);
else
gomp_affinity_init_level_1 (level, level > 3 ? level : 3, count, copy,
name, quiet);
if (gomp_places_list_len == 0)
{
if (!quiet)

View File

@ -701,6 +701,11 @@ parse_places_var (const char *name, bool ignore)
env += 9;
level = 4;
}
else if (strncasecmp (env, "numa_domains", 12) == 0)
{
env += 12;
level = 5;
}
if (level)
{
count = ULONG_MAX;

View File

@ -0,0 +1,10 @@
/* { dg-set-target-env-var OMP_PLACES "numa_domains" } */
#include <omp.h>
int
main ()
{
omp_display_env (0);
return 0;
}