Hi!

This got enacted earlier this week, a couple of routines to query
the affinity.

2015-06-24  Jakub Jelinek  <ja...@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

Reply via email to