diff options
Diffstat (limited to 'libgomp/testsuite/libgomp.c/affinity-1.c')
-rw-r--r-- | libgomp/testsuite/libgomp.c/affinity-1.c | 1146 |
1 files changed, 1146 insertions, 0 deletions
diff --git a/libgomp/testsuite/libgomp.c/affinity-1.c b/libgomp/testsuite/libgomp.c/affinity-1.c new file mode 100644 index 00000000000..5d3e45d1df9 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/affinity-1.c @@ -0,0 +1,1146 @@ +/* Affinity tests. + Copyright (C) 2013 Free Software Foundation, Inc. + + GCC 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. + + GCC 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. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +/* { dg-do run } */ +/* { dg-set-target-env-var OMP_PROC_BIND "false" } */ +/* { dg-additional-options "-DINTERPOSE_GETAFFINITY -DDO_FORK -ldl" { target *-*-linux* } } */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "config.h" +#include <alloca.h> +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef DO_FORK +#include <signal.h> +#endif +#ifdef HAVE_PTHREAD_AFFINITY_NP +#include <sched.h> +#include <pthread.h> +#ifdef INTERPOSE_GETAFFINITY +#include <dlfcn.h> +#endif +#endif + +struct place +{ + int start, len; +}; +struct places +{ + char name[40]; + int count; + struct place places[8]; +} places_array[] = { + { "", 1, { { -1, -1 } } }, + { "{0}:8", 8, + { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 } } }, + { "{7,6}:2:-3", 2, { { 6, 2 }, { 3, 2 } } }, + { "{6,7}:4:-2,!{2,3}", 3, { { 6, 2 }, { 4, 2 }, { 0, 2 } } }, + { "{1}:7:1", 7, + { { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 } } }, + { "{0,1},{3,2,4},{6,5,!6},{6},{7:2:-1,!6}", 5, + { { 0, 2 }, { 2, 3 }, { 5, 1 }, { 6, 1 }, { 7, 1 } } } +}; + +unsigned long contig_cpucount; +unsigned long min_cpusetsize; + +#if defined (HAVE_PTHREAD_AFFINITY_NP) && defined (_SC_NPROCESSORS_CONF) \ + && defined (CPU_ALLOC_SIZE) + +#if defined (RTLD_NEXT) && defined (INTERPOSE_GETAFFINITY) +int (*orig_getaffinity_np) (pthread_t, size_t, cpu_set_t *); + +int +pthread_getaffinity_np (pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset) +{ + int ret; + unsigned long i, max; + if (orig_getaffinity_np == NULL) + { + orig_getaffinity_np = (int (*) (pthread_t, size_t, cpu_set_t *)) + dlsym (RTLD_NEXT, "pthread_getaffinity_np"); + if (orig_getaffinity_np == NULL) + exit (0); + } + ret = orig_getaffinity_np (thread, cpusetsize, cpuset); + if (ret != 0) + return ret; + if (contig_cpucount == 0) + { + max = 8 * cpusetsize; + for (i = 0; i < max; i++) + if (!CPU_ISSET_S (i, cpusetsize, cpuset)) + break; + contig_cpucount = i; + min_cpusetsize = cpusetsize; + } + return ret; +} +#endif + +void +print_affinity (struct place p) +{ + static unsigned long size; + if (size == 0) + { + if (min_cpusetsize) + size = min_cpusetsize; + else + { + size = sysconf (_SC_NPROCESSORS_CONF); + size = CPU_ALLOC_SIZE (size); + if (size < sizeof (cpu_set_t)) + size = sizeof (cpu_set_t); + } + } + cpu_set_t *cpusetp = (cpu_set_t *) alloca (size); + if (pthread_getaffinity_np (pthread_self (), size, cpusetp) == 0) + { + unsigned long i, len, max = 8 * size; + int notfirst = 0, unexpected = 1; + + printf (" bound to {"); + for (i = 0, len = 0; i < max; i++) + if (CPU_ISSET_S (i, size, cpusetp)) + { + if (len == 0) + { + if (notfirst) + { + unexpected = 1; + printf (","); + } + else if (i == (unsigned long) p.start) + unexpected = 0; + notfirst = 1; + printf ("%lu", i); + } + ++len; + } + else + { + if (len && len != (unsigned long) p.len) + unexpected = 1; + if (len > 1) + printf (":%lu", len); + len = 0; + } + if (len && len != (unsigned long) p.len) + unexpected = 1; + if (len > 1) + printf (":%lu", len); + printf ("}"); + if (p.start != -1 && unexpected) + { + printf (", expected {%d", p.start); + if (p.len != 1) + printf (":%d", p.len); + printf ("} instead"); + } + else if (p.start != -1) + printf (", verified"); + } +} +#else +void +print_affinity (struct place p) +{ + (void) p.start; + (void) p.len; +} +#endif + + +int +main () +{ + char *env_proc_bind = getenv ("OMP_PROC_BIND"); + int test_false = env_proc_bind && strcmp (env_proc_bind, "false") == 0; + int test_true = env_proc_bind && strcmp (env_proc_bind, "true") == 0; + int test_spread_master_close + = env_proc_bind && strcmp (env_proc_bind, "spread,master,close") == 0; + char *env_places = getenv ("OMP_PLACES"); + int test_places = 0; + +#ifdef DO_FORK + if (env_places == NULL && contig_cpucount >= 8 && test_false + && getenv ("GOMP_AFFINITY") == NULL) + { + int i, j, status; + pid_t pid; + for (j = 0; j < 2; j++) + { + if (setenv ("OMP_PROC_BIND", j ? "spread,master,close" : "true", 1) + < 0) + break; + for (i = sizeof (places_array) / sizeof (places_array[0]) - 1; + i; --i) + { + if (setenv ("OMP_PLACES", places_array[i].name, 1) < 0) + break; + pid = fork (); + if (pid == -1) + break; + if (pid == 0) + { + execl ("/proc/self/exe", "affinity-1.exe", NULL); + _exit (1); + } + if (waitpid (pid, &status, 0) < 0) + break; + if (WIFSIGNALED (status) && WTERMSIG (status) == SIGABRT) + abort (); + else if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) + break; + } + if (i) + break; + } + } +#endif + + int first = 1; + if (env_proc_bind) + { + printf ("OMP_PROC_BIND='%s'", env_proc_bind); + first = 0; + } + if (env_places) + printf ("%sOMP_PLACES='%s'", first ? "" : " ", env_places); + printf ("\n"); + + if (env_places && contig_cpucount >= 8 + && (test_true || test_spread_master_close)) + { + for (test_places = sizeof (places_array) / sizeof (places_array[0]) - 1; + test_places; --test_places) + if (strcmp (env_places, places_array[test_places].name) == 0) + break; + } + +#define verify(if_true, if_s_m_c) \ + if (test_false && omp_get_proc_bind () != omp_proc_bind_false) \ + abort (); \ + if (test_true && omp_get_proc_bind () != if_true) \ + abort (); \ + if (test_spread_master_close && omp_get_proc_bind () != if_s_m_c) \ + abort (); + + verify (omp_proc_bind_true, omp_proc_bind_spread); + + printf ("Initial thread"); + print_affinity (places_array[test_places].places[0]); + printf ("\n"); + omp_set_nested (1); + omp_set_dynamic (0); + + #pragma omp parallel if (0) + { + verify (omp_proc_bind_true, omp_proc_bind_master); + #pragma omp parallel if (0) + { + verify (omp_proc_bind_true, omp_proc_bind_close); + #pragma omp parallel if (0) + { + verify (omp_proc_bind_true, omp_proc_bind_close); + } + #pragma omp parallel if (0) proc_bind (spread) + { + verify (omp_proc_bind_spread, omp_proc_bind_spread); + } + } + #pragma omp parallel if (0) proc_bind (master) + { + verify (omp_proc_bind_master, omp_proc_bind_close); + #pragma omp parallel if (0) + { + verify (omp_proc_bind_master, omp_proc_bind_close); + } + #pragma omp parallel if (0) proc_bind (spread) + { + verify (omp_proc_bind_spread, omp_proc_bind_spread); + } + } + } + + /* True/spread */ + #pragma omp parallel num_threads (4) + { + verify (omp_proc_bind_true, omp_proc_bind_master); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#1 thread %d", thr); + if (omp_get_num_threads () == 4 && test_spread_master_close) + switch (places_array[test_places].count) + { + case 8: + /* T = 4, P = 8, each subpartition has 2 places. */ + case 7: + /* T = 4, P = 7, each subpartition has 2 places, but + last partition, which has just one place. */ + p = places_array[test_places].places[2 * thr]; + break; + case 5: + /* T = 4, P = 5, first subpartition has 2 places, the + rest just one. */ + p = places_array[test_places].places[thr ? 1 + thr : 0]; + break; + case 3: + /* T = 4, P = 3, unit sized subpartitions, first gets + thr0 and thr3, second thr1, third thr2. */ + p = places_array[test_places].places[thr == 3 ? 0 : thr]; + break; + case 2: + /* T = 4, P = 2, unit sized subpartitions, each with + 2 threads. */ + p = places_array[test_places].places[thr / 2]; + break; + } + print_affinity (p); + printf ("\n"); + } + #pragma omp barrier + if (omp_get_thread_num () == 3) + { + /* True/spread, true/master. */ + #pragma omp parallel num_threads (3) + { + verify (omp_proc_bind_true, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#1,#1 thread 3,%d", thr); + if (omp_get_num_threads () == 3 && test_spread_master_close) + /* Outer is spread, inner master, so just bind to the + place or the master thread, which is thr 3 above. */ + switch (places_array[test_places].count) + { + case 8: + case 7: + p = places_array[test_places].places[6]; + break; + case 5: + p = places_array[test_places].places[4]; + break; + case 3: + p = places_array[test_places].places[0]; + break; + case 2: + p = places_array[test_places].places[1]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + /* True/spread, spread. */ + #pragma omp parallel num_threads (5) proc_bind (spread) + { + verify (omp_proc_bind_spread, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#1,#2 thread 3,%d", thr); + if (omp_get_num_threads () == 5 && test_spread_master_close) + /* Outer is spread, inner spread. */ + switch (places_array[test_places].count) + { + case 8: + /* T = 5, P = 2, unit sized subpartitions. */ + p = places_array[test_places].places[thr == 4 ? 6 + : 6 + thr / 2]; + break; + /* The rest are T = 5, P = 1. */ + case 7: + p = places_array[test_places].places[6]; + break; + case 5: + p = places_array[test_places].places[4]; + break; + case 3: + p = places_array[test_places].places[0]; + break; + case 2: + p = places_array[test_places].places[1]; + break; + } + print_affinity (p); + printf ("\n"); + } + #pragma omp barrier + if (omp_get_thread_num () == 3) + { + /* True/spread, spread, close. */ + #pragma omp parallel num_threads (5) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#1,#2,#1 thread 3,3,%d", thr); + if (omp_get_num_threads () == 5 && test_spread_master_close) + /* Outer is spread, inner spread, innermost close. */ + switch (places_array[test_places].count) + { + /* All are T = 5, P = 1. */ + case 8: + p = places_array[test_places].places[7]; + break; + case 7: + p = places_array[test_places].places[6]; + break; + case 5: + p = places_array[test_places].places[4]; + break; + case 3: + p = places_array[test_places].places[0]; + break; + case 2: + p = places_array[test_places].places[1]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + } + /* True/spread, master. */ + #pragma omp parallel num_threads (4) proc_bind(master) + { + verify (omp_proc_bind_master, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#1,#3 thread 3,%d", thr); + if (omp_get_num_threads () == 4 && test_spread_master_close) + /* Outer is spread, inner master, so just bind to the + place or the master thread, which is thr 3 above. */ + switch (places_array[test_places].count) + { + case 8: + case 7: + p = places_array[test_places].places[6]; + break; + case 5: + p = places_array[test_places].places[4]; + break; + case 3: + p = places_array[test_places].places[0]; + break; + case 2: + p = places_array[test_places].places[1]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + /* True/spread, close. */ + #pragma omp parallel num_threads (6) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#1,#4 thread 3,%d", thr); + if (omp_get_num_threads () == 6 && test_spread_master_close) + /* Outer is spread, inner close. */ + switch (places_array[test_places].count) + { + case 8: + /* T = 6, P = 2, unit sized subpartitions. */ + p = places_array[test_places].places[6 + thr / 3]; + break; + /* The rest are T = 6, P = 1. */ + case 7: + p = places_array[test_places].places[6]; + break; + case 5: + p = places_array[test_places].places[4]; + break; + case 3: + p = places_array[test_places].places[0]; + break; + case 2: + p = places_array[test_places].places[1]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + } + + /* Spread. */ + #pragma omp parallel num_threads (5) proc_bind(spread) + { + verify (omp_proc_bind_spread, omp_proc_bind_master); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#2 thread %d", thr); + if (omp_get_num_threads () == 5 + && (test_spread_master_close || test_true)) + switch (places_array[test_places].count) + { + case 8: + /* T = 5, P = 8, first 3 subpartitions have 2 places, last + 2 one place. */ + p = places_array[test_places].places[thr < 3 ? 2 * thr : 3 + thr]; + break; + case 7: + /* T = 5, P = 7, first 2 subpartitions have 2 places, last + 3 one place. */ + p = places_array[test_places].places[thr < 2 ? 2 * thr : 2 + thr]; + break; + case 5: + /* T = 5, P = 5, unit sized subpartitions, each one with one + thread. */ + p = places_array[test_places].places[thr]; + break; + case 3: + /* T = 5, P = 3, unit sized subpartitions, first gets + thr0 and thr3, second thr1 and thr4, third thr2. */ + p = places_array[test_places].places[thr >= 3 ? thr - 3 : thr]; + break; + case 2: + /* T = 5, P = 2, unit sized subpartitions, first with + thr{0,1,4} and second with thr{2,3}. */ + p = places_array[test_places].places[thr == 4 ? 0 : thr / 2]; + break; + } + print_affinity (p); + printf ("\n"); + } + #pragma omp barrier + if (omp_get_thread_num () == 3) + { + int pp = 0; + switch (places_array[test_places].count) + { + case 8: pp = 6; break; + case 7: pp = 5; break; + case 5: pp = 3; break; + case 2: pp = 1; break; + } + /* Spread, spread/master. */ + #pragma omp parallel num_threads (3) firstprivate (pp) + { + verify (omp_proc_bind_spread, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#2,#1 thread 3,%d", thr); + if (test_spread_master_close || test_true) + /* Outer is spread, inner spread resp. master, bit we have + just unit sized partitions. */ + p = places_array[test_places].places[pp]; + print_affinity (p); + printf ("\n"); + } + } + /* Spread, spread. */ + #pragma omp parallel num_threads (5) proc_bind (spread) \ + firstprivate (pp) + { + verify (omp_proc_bind_spread, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#2,#2 thread 3,%d", thr); + if (test_spread_master_close || test_true) + /* Outer is spread, inner spread, bit we have + just unit sized partitions. */ + p = places_array[test_places].places[pp]; + print_affinity (p); + printf ("\n"); + } + } + /* Spread, master. */ + #pragma omp parallel num_threads (4) proc_bind(master) \ + firstprivate(pp) + { + verify (omp_proc_bind_master, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#2,#3 thread 3,%d", thr); + if (test_spread_master_close || test_true) + /* Outer is spread, inner master, bit we have + just unit sized partitions. */ + p = places_array[test_places].places[pp]; + print_affinity (p); + printf ("\n"); + } + } + /* Spread, close. */ + #pragma omp parallel num_threads (6) proc_bind (close) \ + firstprivate (pp) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#2,#4 thread 3,%d", thr); + if (test_spread_master_close || test_true) + /* Outer is spread, inner close, bit we have + just unit sized partitions. */ + p = places_array[test_places].places[pp]; + print_affinity (p); + printf ("\n"); + } + } + } + } + + /* Master. */ + #pragma omp parallel num_threads (3) proc_bind(master) + { + verify (omp_proc_bind_master, omp_proc_bind_master); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#3 thread %d", thr); + if (test_spread_master_close || test_true) + p = places_array[test_places].places[0]; + print_affinity (p); + printf ("\n"); + } + #pragma omp barrier + if (omp_get_thread_num () == 2) + { + /* Master, master. */ + #pragma omp parallel num_threads (4) + { + verify (omp_proc_bind_master, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#3,#1 thread 2,%d", thr); + if (test_spread_master_close || test_true) + /* Outer is master, inner is master. */ + p = places_array[test_places].places[0]; + print_affinity (p); + printf ("\n"); + } + } + /* Master, spread. */ + #pragma omp parallel num_threads (4) proc_bind (spread) + { + verify (omp_proc_bind_spread, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#3,#2 thread 2,%d", thr); + if (omp_get_num_threads () == 4 + && (test_spread_master_close || test_true)) + /* Outer is master, inner is spread. */ + switch (places_array[test_places].count) + { + case 8: + /* T = 4, P = 8, each subpartition has 2 places. */ + case 7: + /* T = 4, P = 7, each subpartition has 2 places, but + last partition, which has just one place. */ + p = places_array[test_places].places[2 * thr]; + break; + case 5: + /* T = 4, P = 5, first subpartition has 2 places, the + rest just one. */ + p = places_array[test_places].places[thr ? 1 + thr : 0]; + break; + case 3: + /* T = 4, P = 3, unit sized subpartitions, first gets + thr0 and thr3, second thr1, third thr2. */ + p = places_array[test_places].places[thr == 3 ? 0 : thr]; + break; + case 2: + /* T = 4, P = 2, unit sized subpartitions, each with + 2 threads. */ + p = places_array[test_places].places[thr / 2]; + break; + } + print_affinity (p); + printf ("\n"); + } + #pragma omp barrier + if (omp_get_thread_num () == 0) + { + /* Master, spread, close. */ + #pragma omp parallel num_threads (5) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#3,#2,#1 thread 2,0,%d", thr); + if (omp_get_num_threads () == 5 + && (test_spread_master_close || test_true)) + /* Outer is master, inner spread, innermost close. */ + switch (places_array[test_places].count) + { + /* First 3 are T = 5, P = 2. */ + case 8: + case 7: + case 5: + p = places_array[test_places].places[(thr & 2) / 2]; + break; + /* All the rest are T = 5, P = 1. */ + case 3: + case 2: + p = places_array[test_places].places[0]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + #pragma omp barrier + if (omp_get_thread_num () == 3) + { + /* Master, spread, close. */ + #pragma omp parallel num_threads (5) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#3,#2,#2 thread 2,3,%d", thr); + if (omp_get_num_threads () == 5 + && (test_spread_master_close || test_true)) + /* Outer is master, inner spread, innermost close. */ + switch (places_array[test_places].count) + { + case 8: + /* T = 5, P = 2. */ + p = places_array[test_places].places[6 + + (thr & 2) / 2]; + break; + /* All the rest are T = 5, P = 1. */ + case 7: + p = places_array[test_places].places[6]; + break; + case 5: + p = places_array[test_places].places[4]; + break; + case 3: + p = places_array[test_places].places[0]; + break; + case 2: + p = places_array[test_places].places[1]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + } + /* Master, master. */ + #pragma omp parallel num_threads (4) proc_bind(master) + { + verify (omp_proc_bind_master, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#3,#3 thread 2,%d", thr); + if (test_spread_master_close || test_true) + /* Outer is master, inner master. */ + p = places_array[test_places].places[0]; + print_affinity (p); + printf ("\n"); + } + } + /* Master, close. */ + #pragma omp parallel num_threads (6) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#3,#4 thread 2,%d", thr); + if (omp_get_num_threads () == 6 + && (test_spread_master_close || test_true)) + switch (places_array[test_places].count) + { + case 8: + /* T = 6, P = 8. */ + case 7: + /* T = 6, P = 7. */ + p = places_array[test_places].places[thr]; + break; + case 5: + /* T = 6, P = 5. thr{0,5} go into the first place. */ + p = places_array[test_places].places[thr == 5 ? 0 : thr]; + break; + case 3: + /* T = 6, P = 3, two threads into each place. */ + p = places_array[test_places].places[thr / 2]; + break; + case 2: + /* T = 6, P = 2, 3 threads into each place. */ + p = places_array[test_places].places[thr / 3]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + } + + #pragma omp parallel num_threads (5) proc_bind(close) + { + verify (omp_proc_bind_close, omp_proc_bind_master); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4 thread %d", thr); + if (omp_get_num_threads () == 5 + && (test_spread_master_close || test_true)) + switch (places_array[test_places].count) + { + case 8: + /* T = 5, P = 8. */ + case 7: + /* T = 5, P = 7. */ + case 5: + /* T = 5, P = 5. */ + p = places_array[test_places].places[thr]; + break; + case 3: + /* T = 5, P = 3, thr{0,3} in first place, thr{1,4} in second, + thr2 in third. */ + p = places_array[test_places].places[thr >= 3 ? thr - 3 : thr]; + break; + case 2: + /* T = 5, P = 2, thr{0,1,4} in first place, thr{2,3} in second. */ + p = places_array[test_places].places[thr == 4 ? 0 : thr / 2]; + break; + } + print_affinity (p); + printf ("\n"); + } + #pragma omp barrier + if (omp_get_thread_num () == 2) + { + int pp = 0; + switch (places_array[test_places].count) + { + case 8: + case 7: + case 5: + case 3: + pp = 2; + break; + case 2: + pp = 1; + break; + } + /* Close, close/master. */ + #pragma omp parallel num_threads (4) firstprivate (pp) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4,#1 thread 2,%d", thr); + if (test_spread_master_close) + /* Outer is close, inner is master. */ + p = places_array[test_places].places[pp]; + else if (omp_get_num_threads () == 4 && test_true) + /* Outer is close, inner is close. */ + switch (places_array[test_places].count) + { + case 8: + /* T = 4, P = 8. */ + case 7: + /* T = 4, P = 7. */ + p = places_array[test_places].places[2 + thr]; + break; + case 5: + /* T = 4, P = 5. There is wrap-around for thr3. */ + p = places_array[test_places].places[thr == 3 ? 0 : 2 + thr]; + break; + case 3: + /* T = 4, P = 3, thr{0,3} go into p2, thr1 into p0, thr2 + into p1. */ + p = places_array[test_places].places[(2 + thr) % 3]; + break; + case 2: + /* T = 4, P = 2, 2 threads into each place. */ + p = places_array[test_places].places[1 - thr / 2]; + break; + } + + print_affinity (p); + printf ("\n"); + } + } + /* Close, spread. */ + #pragma omp parallel num_threads (4) proc_bind (spread) + { + verify (omp_proc_bind_spread, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4,#2 thread 2,%d", thr); + if (omp_get_num_threads () == 4 + && (test_spread_master_close || test_true)) + /* Outer is close, inner is spread. */ + switch (places_array[test_places].count) + { + case 8: + /* T = 4, P = 8, each subpartition has 2 places. */ + case 7: + /* T = 4, P = 7, each subpartition has 2 places, but + last partition, which has just one place. */ + p = places_array[test_places].places[thr == 3 ? 0 + : 2 + 2 * thr]; + break; + case 5: + /* T = 4, P = 5, first subpartition has 2 places, the + rest just one. */ + p = places_array[test_places].places[thr == 3 ? 0 + : 2 + thr]; + break; + case 3: + /* T = 4, P = 3, unit sized subpartitions, third gets + thr0 and thr3, first thr1, second thr2. */ + p = places_array[test_places].places[thr == 0 ? 2 : thr - 1]; + break; + case 2: + /* T = 4, P = 2, unit sized subpartitions, each with + 2 threads. */ + p = places_array[test_places].places[1 - thr / 2]; + break; + } + print_affinity (p); + printf ("\n"); + } + #pragma omp barrier + if (omp_get_thread_num () == 0) + { + /* Close, spread, close. */ + #pragma omp parallel num_threads (5) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4,#2,#1 thread 2,0,%d", thr); + if (omp_get_num_threads () == 5 + && (test_spread_master_close || test_true)) + /* Outer is close, inner spread, innermost close. */ + switch (places_array[test_places].count) + { + case 8: + case 7: + /* T = 5, P = 2. */ + p = places_array[test_places].places[2 + + (thr & 2) / 2]; + break; + /* All the rest are T = 5, P = 1. */ + case 5: + case 3: + p = places_array[test_places].places[2]; + break; + case 2: + p = places_array[test_places].places[1]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + #pragma omp barrier + if (omp_get_thread_num () == 2) + { + /* Close, spread, close. */ + #pragma omp parallel num_threads (5) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4,#2,#2 thread 2,2,%d", thr); + if (omp_get_num_threads () == 5 + && (test_spread_master_close || test_true)) + /* Outer is close, inner spread, innermost close. */ + switch (places_array[test_places].count) + { + case 8: + /* T = 5, P = 2. */ + p = places_array[test_places].places[6 + + (thr & 2) / 2]; + break; + /* All the rest are T = 5, P = 1. */ + case 7: + p = places_array[test_places].places[6]; + break; + case 5: + p = places_array[test_places].places[4]; + break; + case 3: + p = places_array[test_places].places[1]; + break; + case 2: + p = places_array[test_places].places[0]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + #pragma omp barrier + if (omp_get_thread_num () == 3) + { + /* Close, spread, close. */ + #pragma omp parallel num_threads (5) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4,#2,#3 thread 2,3,%d", thr); + if (omp_get_num_threads () == 5 + && (test_spread_master_close || test_true)) + /* Outer is close, inner spread, innermost close. */ + switch (places_array[test_places].count) + { + case 8: + case 7: + case 5: + /* T = 5, P = 2. */ + p = places_array[test_places].places[(thr & 2) / 2]; + break; + /* All the rest are T = 5, P = 1. */ + case 3: + p = places_array[test_places].places[2]; + break; + case 2: + p = places_array[test_places].places[0]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + } + /* Close, master. */ + #pragma omp parallel num_threads (4) proc_bind(master) \ + firstprivate (pp) + { + verify (omp_proc_bind_master, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4,#3 thread 2,%d", thr); + if (test_spread_master_close || test_true) + /* Outer is close, inner master. */ + p = places_array[test_places].places[pp]; + print_affinity (p); + printf ("\n"); + } + } + /* Close, close. */ + #pragma omp parallel num_threads (6) proc_bind (close) + { + verify (omp_proc_bind_close, omp_proc_bind_close); + #pragma omp critical + { + struct place p = places_array[0].places[0]; + int thr = omp_get_thread_num (); + printf ("#4,#4 thread 2,%d", thr); + if (omp_get_num_threads () == 6 + && (test_spread_master_close || test_true)) + switch (places_array[test_places].count) + { + case 8: + /* T = 6, P = 8. */ + p = places_array[test_places].places[2 + thr]; + break; + case 7: + /* T = 6, P = 7. */ + p = places_array[test_places].places[thr == 5 ? 0 : 2 + thr]; + break; + case 5: + /* T = 6, P = 5. thr{0,5} go into the third place. */ + p = places_array[test_places].places[thr >= 3 ? thr - 3 + : 2 + thr]; + break; + case 3: + /* T = 6, P = 3, two threads into each place. */ + p = places_array[test_places].places[thr < 2 ? 2 + : thr / 2 - 1]; + break; + case 2: + /* T = 6, P = 2, 3 threads into each place. */ + p = places_array[test_places].places[1 - thr / 3]; + break; + } + print_affinity (p); + printf ("\n"); + } + } + } + } + + return 0; +} |