This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp4.1] Add affinity query routines
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 24 Jun 2015 12:13:51 +0200
- Subject: [gomp4.1] Add affinity query routines
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This got enacted earlier this week, a couple of routines to query
the affinity.
2015-06-24 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (omp_get_num_places, omp_get_place_num_procs,
omp_get_place_proc_ids, omp_get_place_num,
omp_get_partition_num_places, omp_get_partition_place_nums): New
prototypes.
* omp_lib.f90.in (omp_get_num_places, omp_get_place_num_procs,
omp_get_place_proc_ids, omp_get_place_num,
omp_get_partition_num_places, omp_get_partition_place_nums): New
interfaces.
* omp_lib.h.in (omp_get_num_places, omp_get_place_num_procs,
omp_get_place_proc_ids, omp_get_place_num,
omp_get_partition_num_places, omp_get_partition_place_nums): New
externs.
* libgomp.map (OMP_4.1): Export omp_get_num_places,
omp_get_place_num_procs, omp_get_place_proc_ids, omp_get_place_num,
omp_get_partition_num_places, omp_get_partition_place_nums,
omp_get_num_places_, omp_get_place_num_procs_,
omp_get_place_num_procs_8_, omp_get_place_proc_ids_,
omp_get_place_proc_ids_8_, omp_get_place_num_,
omp_get_partition_num_places_, omp_get_partition_place_nums_
and omp_get_partition_place_nums_8_.
* libgomp.h (gomp_get_place_proc_ids_8): New prototype.
* env.c (omp_get_num_places, omp_get_place_num,
omp_get_partition_num_places, omp_get_partition_place_nums): New
functions, add ialias for them.
* fortran.c (omp_get_num_places, omp_get_place_num,
omp_get_partition_num_places, omp_get_partition_place_nums,
omp_get_place_num_procs, omp_get_place_proc_ids): New
ialias_redirects.
(omp_get_num_places_, omp_get_place_num_procs_,
omp_get_place_num_procs_8_, omp_get_place_proc_ids_,
omp_get_place_proc_ids_8_, omp_get_place_num_,
omp_get_partition_num_places_, omp_get_partition_place_nums_,
omp_get_partition_place_nums_8_): New functions.
* config/linux/affinity.c (omp_get_place_num_procs,
omp_get_place_proc_ids, gomp_get_place_proc_ids_8): New functions.
* config/posix/affinity.c (omp_get_place_num_procs,
omp_get_place_proc_ids, gomp_get_place_proc_ids_8): New functions.
* testsuite/libgomp.c/affinity-2.c: New test.
* testsuite/libgomp.fortran/affinity1.f90: New test.
* testsuite/libgomp.fortran/affinity2.f90: New test.
--- libgomp/omp.h.in.jj 2015-06-12 16:45:16.000000000 +0200
+++ libgomp/omp.h.in 2015-06-23 19:24:15.056053879 +0200
@@ -125,6 +125,12 @@ extern int omp_in_final (void) __GOMP_NO
extern int omp_get_cancellation (void) __GOMP_NOTHROW;
extern omp_proc_bind_t omp_get_proc_bind (void) __GOMP_NOTHROW;
+extern int omp_get_num_places (void) __GOMP_NOTHROW;
+extern int omp_get_place_num_procs (int) __GOMP_NOTHROW;
+extern void omp_get_place_proc_ids (int, int *) __GOMP_NOTHROW;
+extern int omp_get_place_num (void) __GOMP_NOTHROW;
+extern int omp_get_partition_num_places (void) __GOMP_NOTHROW;
+extern void omp_get_partition_place_nums (int *) __GOMP_NOTHROW;
extern void omp_set_default_device (int) __GOMP_NOTHROW;
extern int omp_get_default_device (void) __GOMP_NOTHROW;
--- libgomp/omp_lib.f90.in.jj 2015-06-12 17:34:56.000000000 +0200
+++ libgomp/omp_lib.f90.in 2015-06-24 11:49:40.159360460 +0200
@@ -330,6 +330,58 @@
end function omp_get_proc_bind
end interface
+ interface
+ function omp_get_num_places ()
+ integer (4) :: omp_get_num_places
+ end function omp_get_num_places
+ end interface
+
+ interface omp_get_place_num_procs
+ function omp_get_place_num_procs (place_num)
+ integer (4), intent(in) :: place_num
+ integer (4) :: omp_get_place_num_procs
+ end function omp_get_place_num_procs
+
+ function omp_get_place_num_procs_8 (place_num)
+ integer (8), intent(in) :: place_num
+ integer (4) :: omp_get_place_num_procs_8
+ end function omp_get_place_num_procs_8
+ end interface
+
+ interface omp_get_place_proc_ids
+ subroutine omp_get_place_proc_ids (place_num, ids)
+ integer (4), intent(in) :: place_num
+ integer (4), intent(out) :: ids(*)
+ end subroutine omp_get_place_proc_ids
+
+ subroutine omp_get_place_proc_ids_8 (place_num, ids)
+ integer (8), intent(in) :: place_num
+ integer (8), intent(out) :: ids(*)
+ end subroutine omp_get_place_proc_ids_8
+ end interface
+
+ interface
+ function omp_get_place_num ()
+ integer (4) :: omp_get_place_num
+ end function omp_get_place_num
+ end interface
+
+ interface
+ function omp_get_partition_num_places ()
+ integer (4) :: omp_get_partition_num_places
+ end function omp_get_partition_num_places
+ end interface
+
+ interface omp_get_partition_place_nums
+ subroutine omp_get_partition_place_nums (place_nums)
+ integer (4), intent(out) :: place_nums(*)
+ end subroutine omp_get_partition_place_nums
+
+ subroutine omp_get_partition_place_nums_8 (place_nums)
+ integer (8), intent(out) :: place_nums(*)
+ end subroutine omp_get_partition_place_nums_8
+ end interface
+
interface omp_set_default_device
subroutine omp_set_default_device (device_num)
integer (4), intent (in) :: device_num
--- libgomp/omp_lib.h.in.jj 2015-06-12 17:32:10.000000000 +0200
+++ libgomp/omp_lib.h.in 2015-06-23 18:27:34.467368445 +0200
@@ -102,6 +102,17 @@
external omp_get_proc_bind
integer(omp_proc_bind_kind) omp_get_proc_bind
+ integer(4) omp_get_num_places
+ external omp_get_num_places
+ integer(4) omp_get_place_num_procs
+ external omp_get_place_num_procs
+ external omp_get_place_proc_ids
+ integer(4) omp_get_place_num
+ external omp_get_place_num
+ integer(4) omp_get_partition_num_places
+ external omp_get_partition_num_places
+ external omp_get_partition_place_nums
+
external omp_set_default_device, omp_get_default_device
external omp_get_num_devices, omp_get_num_teams
external omp_get_team_num
--- libgomp/libgomp.map.jj 2015-06-17 20:53:27.000000000 +0200
+++ libgomp/libgomp.map 2015-06-23 19:15:16.499197139 +0200
@@ -138,6 +138,21 @@ OMP_4.1 {
global:
omp_get_max_task_priority;
omp_get_max_task_priority_;
+ omp_get_num_places;
+ omp_get_num_places_;
+ omp_get_place_num_procs;
+ omp_get_place_num_procs_;
+ omp_get_place_num_procs_8_;
+ omp_get_place_proc_ids;
+ omp_get_place_proc_ids_;
+ omp_get_place_proc_ids_8_;
+ omp_get_place_num;
+ omp_get_place_num_;
+ omp_get_partition_num_places;
+ omp_get_partition_num_places_;
+ omp_get_partition_place_nums;
+ omp_get_partition_place_nums_;
+ omp_get_partition_place_nums_8_;
} OMP_4.0;
GOMP_1.0 {
--- libgomp/libgomp.h.jj 2015-06-23 16:23:45.000000000 +0200
+++ libgomp/libgomp.h 2015-06-24 11:31:02.747693973 +0200
@@ -526,6 +526,7 @@ extern bool gomp_affinity_same_place (vo
extern bool gomp_affinity_finalize_place_list (bool);
extern bool gomp_affinity_init_level (int, unsigned long, bool);
extern void gomp_affinity_print_place (void *);
+extern void gomp_get_place_proc_ids_8 (int, int64_t *);
/* alloc.c */
--- libgomp/env.c.jj 2015-06-11 10:26:11.000000000 +0200
+++ libgomp/env.c 2015-06-24 11:32:32.540302279 +0200
@@ -1460,6 +1460,53 @@ omp_is_initial_device (void)
return 1;
}
+int
+omp_get_num_places (void)
+{
+ return gomp_places_list_len;
+}
+
+int
+omp_get_place_num (void)
+{
+ if (gomp_places_list == NULL)
+ return -1;
+
+ struct gomp_thread *thr = gomp_thread ();
+ if (thr->place == 0)
+ gomp_init_affinity ();
+
+ return (int) thr->place - 1;
+}
+
+int
+omp_get_partition_num_places (void)
+{
+ if (gomp_places_list == NULL)
+ return 0;
+
+ struct gomp_thread *thr = gomp_thread ();
+ if (thr->place == 0)
+ gomp_init_affinity ();
+
+ return thr->ts.place_partition_len;
+}
+
+void
+omp_get_partition_place_nums (int *place_nums)
+{
+ if (gomp_places_list == NULL)
+ return;
+
+ struct gomp_thread *thr = gomp_thread ();
+ if (thr->place == 0)
+ gomp_init_affinity ();
+
+ unsigned int i;
+ for (i = 0; i < thr->ts.place_partition_len; i++)
+ *place_nums++ = thr->ts.place_partition_off + i;
+}
+
ialias (omp_set_dynamic)
ialias (omp_set_nested)
ialias (omp_set_num_threads)
@@ -1480,3 +1527,7 @@ ialias (omp_get_num_teams)
ialias (omp_get_team_num)
ialias (omp_is_initial_device)
ialias (omp_get_max_task_priority)
+ialias (omp_get_num_places)
+ialias (omp_get_place_num)
+ialias (omp_get_partition_num_places)
+ialias (omp_get_partition_place_nums)
--- libgomp/fortran.c.jj 2015-06-11 10:22:33.000000000 +0200
+++ libgomp/fortran.c 2015-06-24 11:16:09.256574057 +0200
@@ -68,6 +68,12 @@ ialias_redirect (omp_get_active_level)
ialias_redirect (omp_in_final)
ialias_redirect (omp_get_cancellation)
ialias_redirect (omp_get_proc_bind)
+ialias_redirect (omp_get_num_places)
+ialias_redirect (omp_get_place_num_procs)
+ialias_redirect (omp_get_place_proc_ids)
+ialias_redirect (omp_get_place_num)
+ialias_redirect (omp_get_partition_num_places)
+ialias_redirect (omp_get_partition_place_nums)
ialias_redirect (omp_set_default_device)
ialias_redirect (omp_get_default_device)
ialias_redirect (omp_get_num_devices)
@@ -453,6 +459,69 @@ omp_get_proc_bind_ (void)
return omp_get_proc_bind ();
}
+int32_t
+omp_get_num_places_ (void)
+{
+ return omp_get_num_places ();
+}
+
+int32_t
+omp_get_place_num_procs_ (const int32_t *place_num)
+{
+ return omp_get_place_num_procs (*place_num);
+}
+
+int32_t
+omp_get_place_num_procs_8_ (const int64_t *place_num)
+{
+ return omp_get_place_num_procs (TO_INT (*place_num));
+}
+
+void
+omp_get_place_proc_ids_ (const int32_t *place_num, int32_t *ids)
+{
+ omp_get_place_proc_ids (*place_num, ids);
+}
+
+void
+omp_get_place_proc_ids_8_ (const int64_t *place_num, int64_t *ids)
+{
+ gomp_get_place_proc_ids_8 (TO_INT (*place_num), ids);
+}
+
+int32_t
+omp_get_place_num_ (void)
+{
+ return omp_get_place_num ();
+}
+
+int32_t
+omp_get_partition_num_places_ (void)
+{
+ return omp_get_partition_num_places ();
+}
+
+void
+omp_get_partition_place_nums_ (int32_t *place_nums)
+{
+ omp_get_partition_place_nums (place_nums);
+}
+
+void
+omp_get_partition_place_nums_8_ (int64_t *place_nums)
+{
+ if (gomp_places_list == NULL)
+ return;
+
+ struct gomp_thread *thr = gomp_thread ();
+ if (thr->place == 0)
+ gomp_init_affinity ();
+
+ unsigned int i;
+ for (i = 0; i < thr->ts.place_partition_len; i++)
+ *place_nums++ = (int64_t) thr->ts.place_partition_off + i;
+}
+
void
omp_set_default_device_ (const int32_t *device_num)
{
--- libgomp/config/linux/affinity.c.jj 2015-04-24 12:30:40.000000000 +0200
+++ libgomp/config/linux/affinity.c 2015-06-24 11:13:58.861602689 +0200
@@ -353,6 +353,45 @@ gomp_affinity_print_place (void *p)
fprintf (stderr, ":%lu", len);
}
+int
+omp_get_place_num_procs (int place_num)
+{
+ if (place_num < 0 || place_num >= gomp_places_list_len)
+ return 0;
+
+ cpu_set_t *cpusetp = (cpu_set_t *) gomp_places_list[place_num];
+ return gomp_cpuset_popcount (gomp_cpuset_size, cpusetp);
+}
+
+void
+omp_get_place_proc_ids (int place_num, int *ids)
+{
+ if (place_num < 0 || place_num >= gomp_places_list_len)
+ return;
+
+ cpu_set_t *cpusetp = (cpu_set_t *) gomp_places_list[place_num];
+ unsigned long i, max = 8 * gomp_cpuset_size;
+ for (i = 0; i < max; i++)
+ if (CPU_ISSET_S (i, gomp_cpuset_size, cpusetp))
+ *ids++ = i;
+}
+
+void
+gomp_get_place_proc_ids_8 (int place_num, int64_t *ids)
+{
+ if (place_num < 0 || place_num >= gomp_places_list_len)
+ return;
+
+ cpu_set_t *cpusetp = (cpu_set_t *) gomp_places_list[place_num];
+ unsigned long i, max = 8 * gomp_cpuset_size;
+ for (i = 0; i < max; i++)
+ if (CPU_ISSET_S (i, gomp_cpuset_size, cpusetp))
+ *ids++ = i;
+}
+
+ialias(omp_get_place_num_procs)
+ialias(omp_get_place_proc_ids)
+
#else
#include "../posix/affinity.c"
--- libgomp/config/posix/affinity.c.jj 2015-04-24 12:30:40.000000000 +0200
+++ libgomp/config/posix/affinity.c 2015-06-24 11:14:18.003304890 +0200
@@ -114,3 +114,27 @@ gomp_affinity_print_place (void *p)
{
(void) p;
}
+
+int
+omp_get_place_num_procs (int place_num)
+{
+ (void) place_num;
+ return 0;
+}
+
+void
+omp_get_place_proc_ids (int place_num, int *ids)
+{
+ (void) place_num;
+ (void) ids;
+}
+
+void
+gomp_get_place_proc_ids_8 (int place_num, int64_t *ids)
+{
+ (void) place_num;
+ (void) ids;
+}
+
+ialias(omp_get_place_num_procs)
+ialias(omp_get_place_proc_ids)
--- libgomp/testsuite/libgomp.c/affinity-2.c.jj 2015-06-24 10:36:16.084810952 +0200
+++ libgomp/testsuite/libgomp.c/affinity-2.c 2015-06-24 10:37:05.381043990 +0200
@@ -0,0 +1,89 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var OMP_PROC_BIND "spread,close" } */
+/* { dg-set-target-env-var OMP_PLACES "{6,7}:4:-2,!{2,3}" } */
+/* { dg-set-target-env-var OMP_NUM_THREADS "2" } */
+
+#include <omp.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int *
+get_buf (int nump)
+{
+ static int *buf;
+ static size_t buf_size;
+ if ((size_t) nump > buf_size)
+ {
+ buf_size *= 2;
+ if (nump > buf_size)
+ buf_size = nump + 64;
+ int *bufn = realloc (buf, buf_size * sizeof (int));
+ if (bufn == NULL)
+ {
+ fprintf (stderr, "memory allocation error\n");
+ exit (1);
+ }
+ buf = bufn;
+ }
+ return buf;
+}
+
+void
+print_place (int count, int *ids)
+{
+ int i, j;
+ printf ("{");
+ for (i = 0; i < count; i++)
+ {
+ for (j = i + 1; j < count; j++)
+ if (ids[j] != ids[i] + (j - i))
+ break;
+ if (i)
+ printf (",");
+ if (j == i + 1)
+ printf ("%d", ids[i]);
+ else
+ {
+ printf ("%d:%d", ids[i], j - i);
+ i = j - 1;
+ }
+ }
+ printf ("}\n");
+}
+
+void
+print_place_var (void)
+{
+ int place = omp_get_place_num ();
+ int num_places = omp_get_partition_num_places ();
+ int *ids = get_buf (num_places);
+ omp_get_partition_place_nums (ids);
+ printf ("place %d\n", place);
+ if (num_places)
+ printf ("partition %d-%d\n", ids[0], ids[num_places - 1]);
+}
+
+int
+main ()
+{
+ int i, num = omp_get_num_places (), nump, *ids;
+ printf ("omp_get_num_places () == %d\n", num);
+ for (i = 0; i < num; i++)
+ {
+ printf ("place %d ", i);
+ nump = omp_get_place_num_procs (i);
+ ids = get_buf (nump);
+ omp_get_place_proc_ids (i, ids);
+ print_place (nump, ids);
+ }
+ print_place_var ();
+ omp_set_nested (1);
+ #pragma omp parallel
+ if (omp_get_thread_num () == omp_get_num_threads () - 1)
+ {
+ #pragma omp parallel
+ if (omp_get_thread_num () == omp_get_num_threads () - 1)
+ print_place_var ();
+ }
+ return 0;
+}
--- libgomp/testsuite/libgomp.fortran/affinity1.f90.jj 2015-06-24 11:26:26.468976017 +0200
+++ libgomp/testsuite/libgomp.fortran/affinity1.f90 2015-06-24 11:51:10.287960552 +0200
@@ -0,0 +1,49 @@
+! { dg-do run }
+! { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } }
+! { dg-set-target-env-var OMP_PROC_BIND "spread,close" }
+! { dg-set-target-env-var OMP_PLACES "{6,7}:4:-2,!{2,3}" }
+! { dg-set-target-env-var OMP_NUM_THREADS "2" }
+
+ use omp_lib
+ integer :: num, i, nump
+ num = omp_get_num_places ()
+ print *, 'omp_get_num_places () == ', num
+ do i = 0, num - 1
+ nump = omp_get_place_num_procs (place_num = i)
+ if (nump .eq. 0) then
+ print *, 'place ', i, ' {}'
+ else
+ call print_place (i, nump)
+ end if
+ end do
+ call print_place_var
+ call omp_set_nested (nested = .true.)
+ !$omp parallel
+ if (omp_get_thread_num () == omp_get_num_threads () - 1) then
+ !$omp parallel
+ if (omp_get_thread_num () == omp_get_num_threads () - 1) &
+ call print_place_var
+ !$omp end parallel
+ end if
+ !$omp end parallel
+contains
+ subroutine print_place (i, nump)
+ integer, intent (in) :: i, nump
+ integer :: ids(nump)
+ call omp_get_place_proc_ids (place_num = i, ids = ids)
+ print *, 'place ', i, ' {', ids, '}'
+ end subroutine
+ subroutine print_place_var
+ integer :: place, num_places
+ place = omp_get_place_num ()
+ num_places = omp_get_partition_num_places ()
+ print *, 'place ', place
+ if (num_places .gt. 0) call print_partition (num_places)
+ end subroutine
+ subroutine print_partition (num_places)
+ integer, intent (in) :: num_places
+ integer :: place_nums(num_places)
+ call omp_get_partition_place_nums (place_nums = place_nums)
+ print *, 'partition ', place_nums(1), '-', place_nums(num_places)
+ end subroutine
+end
--- libgomp/testsuite/libgomp.fortran/affinity2.f90.jj 2015-06-24 11:48:02.045884392 +0200
+++ libgomp/testsuite/libgomp.fortran/affinity2.f90 2015-06-24 11:51:18.506832894 +0200
@@ -0,0 +1,8 @@
+! { dg-do run }
+! { dg-additional-options "-fdefault-integer-8" }
+! { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O2" } }
+! { dg-set-target-env-var OMP_PROC_BIND "spread,close" }
+! { dg-set-target-env-var OMP_PLACES "{6,7}:4:-2,!{2,3}" }
+! { dg-set-target-env-var OMP_NUM_THREADS "2" }
+
+include 'affinity1.f90'
Jakub