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