]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libgomp/testsuite/libgomp.c/affinity-1.c
bdb869c6de1608d086604c2217be04f00d88290c
2 Copyright (C) 2013-2023 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 3, or (at your option) any later
9 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
19 /* { dg-set-target-env-var OMP_PROC_BIND "false" } */
20 /* { dg-additional-options "-Wno-deprecated-declarations" } */
21 /* { dg-additional-options "-DINTERPOSE_GETAFFINITY -DDO_FORK -ldl -Wno-deprecated-declarations" { target *-*-linux* } } */
37 #ifdef HAVE_PTHREAD_AFFINITY_NP
40 #ifdef INTERPOSE_GETAFFINITY
53 struct place places
[8];
55 { "", 1, { { -1, -1 } } },
57 { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 },
58 { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 } } },
59 { "{7,6}:2:-3", 2, { { 6, 2 }, { 3, 2 } } },
60 { "{6,7}:4:-2,!{2,3}", 3, { { 6, 2 }, { 4, 2 }, { 0, 2 } } },
62 { { 1, 1 }, { 2, 1 }, { 3, 1 },
63 { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 } } },
64 { "{0,1},{3,2,4},{6,5,!6},{6},{7:2:-1,!6}", 5,
65 { { 0, 2 }, { 2, 3 }, { 5, 1 }, { 6, 1 }, { 7, 1 } } },
66 { "1,2,{2,3,!2},3,3,!3,!{5:3:-1,!4,!5},{4},5,!4,!5,"
67 "1:2,!{1},!2,7:3:-2,!{5},!7,!3", 3,
68 { { 1, 1 }, { 2, 1 }, { 3, 1 } } }
71 unsigned long contig_cpucount
;
72 unsigned long min_cpusetsize
;
74 #if defined (HAVE_PTHREAD_AFFINITY_NP) && defined (_SC_NPROCESSORS_CONF) \
75 && defined (CPU_ALLOC_SIZE)
77 #if defined (RTLD_NEXT) && defined (INTERPOSE_GETAFFINITY)
78 int (*orig_getaffinity_np
) (pthread_t
, size_t, cpu_set_t
*);
81 pthread_getaffinity_np (pthread_t thread
, size_t cpusetsize
, cpu_set_t
*cpuset
)
85 if (orig_getaffinity_np
== NULL
)
87 orig_getaffinity_np
= (int (*) (pthread_t
, size_t, cpu_set_t
*))
88 dlsym (RTLD_NEXT
, "pthread_getaffinity_np");
89 if (orig_getaffinity_np
== NULL
)
92 ret
= orig_getaffinity_np (thread
, cpusetsize
, cpuset
);
95 if (contig_cpucount
== 0)
98 for (i
= 0; i
< max
; i
++)
99 if (!CPU_ISSET_S (i
, cpusetsize
, cpuset
))
102 min_cpusetsize
= cpusetsize
;
109 print_affinity (struct place p
)
111 static unsigned long size
;
115 size
= min_cpusetsize
;
118 size
= sysconf (_SC_NPROCESSORS_CONF
);
119 size
= CPU_ALLOC_SIZE (size
);
120 if (size
< sizeof (cpu_set_t
))
121 size
= sizeof (cpu_set_t
);
124 cpu_set_t
*cpusetp
= (cpu_set_t
*) __builtin_alloca (size
);
125 if (pthread_getaffinity_np (pthread_self (), size
, cpusetp
) == 0)
127 unsigned long i
, len
, max
= 8 * size
;
128 int notfirst
= 0, unexpected
= 1;
130 printf (" bound to {");
131 for (i
= 0, len
= 0; i
< max
; i
++)
132 if (CPU_ISSET_S (i
, size
, cpusetp
))
141 else if (i
== (unsigned long) p
.start
)
150 if (len
&& len
!= (unsigned long) p
.len
)
153 printf (":%lu", len
);
156 if (len
&& len
!= (unsigned long) p
.len
)
159 printf (":%lu", len
);
161 if (p
.start
!= -1 && unexpected
)
163 printf (", expected {%d", p
.start
);
165 printf (":%d", p
.len
);
166 printf ("} instead");
168 else if (p
.start
!= -1)
169 printf (", verified");
174 print_affinity (struct place p
)
185 char *env_proc_bind
= getenv ("OMP_PROC_BIND");
186 int test_false
= env_proc_bind
&& strcmp (env_proc_bind
, "false") == 0;
187 int test_true
= env_proc_bind
&& strcmp (env_proc_bind
, "true") == 0;
188 int test_spread_master_close
190 && (strcmp (env_proc_bind
, "spread,master,close") == 0
191 || strcmp (env_proc_bind
, "spread,primary,close") == 0));
192 char *env_places
= getenv ("OMP_PLACES");
195 if (omp_proc_bind_master
!= omp_proc_bind_primary
)
199 if (env_places
== NULL
&& contig_cpucount
>= 8 && test_false
200 && getenv ("GOMP_AFFINITY") == NULL
)
204 for (j
= 0; j
< 3; j
++)
206 if (setenv ("OMP_PROC_BIND",
207 j
> 1 ? "spread,primary,close"
208 : (j
? "spread,master,close" : "true"), 1) < 0)
210 for (i
= sizeof (places_array
) / sizeof (places_array
[0]) - 1;
213 if (setenv ("OMP_PLACES", places_array
[i
].name
, 1) < 0)
220 execl ("/proc/self/exe", "affinity-1.exe", NULL
);
223 if (waitpid (pid
, &status
, 0) < 0)
225 if (WIFSIGNALED (status
) && WTERMSIG (status
) == SIGABRT
)
227 else if (!WIFEXITED (status
) || WEXITSTATUS (status
) != 0)
239 printf ("OMP_PROC_BIND='%s'", env_proc_bind
);
243 printf ("%sOMP_PLACES='%s'", first
? "" : " ", env_places
);
246 if (env_places
&& contig_cpucount
>= 8
247 && (test_true
|| test_spread_master_close
))
249 for (test_places
= sizeof (places_array
) / sizeof (places_array
[0]) - 1;
250 test_places
; --test_places
)
251 if (strcmp (env_places
, places_array
[test_places
].name
) == 0)
255 #define verify(if_true, if_s_m_c) \
256 if (test_false && omp_get_proc_bind () != omp_proc_bind_false) \
258 if (test_true && omp_get_proc_bind () != if_true) \
260 if (test_spread_master_close && omp_get_proc_bind () != if_s_m_c) \
263 verify (omp_proc_bind_true
, omp_proc_bind_spread
);
265 printf ("Initial thread");
266 print_affinity (places_array
[test_places
].places
[0]);
271 #pragma omp parallel if (0)
273 verify (omp_proc_bind_true
, omp_proc_bind_master
);
274 #pragma omp parallel if (0)
276 verify (omp_proc_bind_true
, omp_proc_bind_close
);
277 #pragma omp parallel if (0)
279 verify (omp_proc_bind_true
, omp_proc_bind_close
);
281 #pragma omp parallel if (0) proc_bind (spread)
283 verify (omp_proc_bind_spread
, omp_proc_bind_spread
);
286 #pragma omp parallel if (0) proc_bind (master)
288 verify (omp_proc_bind_master
, omp_proc_bind_close
);
289 #pragma omp parallel if (0)
291 verify (omp_proc_bind_master
, omp_proc_bind_close
);
293 #pragma omp parallel if (0) proc_bind (spread)
295 verify (omp_proc_bind_spread
, omp_proc_bind_spread
);
301 #pragma omp parallel num_threads (4)
303 verify (omp_proc_bind_true
, omp_proc_bind_master
);
306 struct place p
= places_array
[0].places
[0];
307 int thr
= omp_get_thread_num ();
308 printf ("#1 thread %d", thr
);
309 if (omp_get_num_threads () == 4 && test_spread_master_close
)
310 switch (places_array
[test_places
].count
)
313 /* T = 4, P = 8, each subpartition has 2 places. */
315 /* T = 4, P = 7, each subpartition has 2 places, but
316 last partition, which has just one place. */
317 p
= places_array
[test_places
].places
[2 * thr
];
320 /* T = 4, P = 5, first subpartition has 2 places, the
322 p
= places_array
[test_places
].places
[thr
? 1 + thr
: 0];
325 /* T = 4, P = 3, unit sized subpartitions, first gets
326 thr0 and thr3, second thr1, third thr2. */
327 p
= places_array
[test_places
].places
[thr
== 3 ? 0 : thr
];
330 /* T = 4, P = 2, unit sized subpartitions, each with
332 p
= places_array
[test_places
].places
[thr
/ 2];
339 if (omp_get_thread_num () == 3)
341 /* True/spread, true/master. */
342 #pragma omp parallel num_threads (3)
344 verify (omp_proc_bind_true
, omp_proc_bind_close
);
347 struct place p
= places_array
[0].places
[0];
348 int thr
= omp_get_thread_num ();
349 printf ("#1,#1 thread 3,%d", thr
);
350 if (omp_get_num_threads () == 3 && test_spread_master_close
)
351 /* Outer is spread, inner master, so just bind to the
352 place or the master thread, which is thr 3 above. */
353 switch (places_array
[test_places
].count
)
357 p
= places_array
[test_places
].places
[6];
360 p
= places_array
[test_places
].places
[4];
363 p
= places_array
[test_places
].places
[0];
366 p
= places_array
[test_places
].places
[1];
373 /* True/spread, spread. */
374 #pragma omp parallel num_threads (5) proc_bind (spread)
376 verify (omp_proc_bind_spread
, omp_proc_bind_close
);
379 struct place p
= places_array
[0].places
[0];
380 int thr
= omp_get_thread_num ();
381 printf ("#1,#2 thread 3,%d", thr
);
382 if (omp_get_num_threads () == 5 && test_spread_master_close
)
383 /* Outer is spread, inner spread. */
384 switch (places_array
[test_places
].count
)
387 /* T = 5, P = 2, unit sized subpartitions. */
388 p
= places_array
[test_places
].places
[thr
== 4 ? 6
391 /* The rest are T = 5, P = 1. */
393 p
= places_array
[test_places
].places
[6];
396 p
= places_array
[test_places
].places
[4];
399 p
= places_array
[test_places
].places
[0];
402 p
= places_array
[test_places
].places
[1];
409 if (omp_get_thread_num () == 3)
411 /* True/spread, spread, close. */
412 #pragma omp parallel num_threads (5) proc_bind (close)
414 verify (omp_proc_bind_close
, omp_proc_bind_close
);
417 struct place p
= places_array
[0].places
[0];
418 int thr
= omp_get_thread_num ();
419 printf ("#1,#2,#1 thread 3,3,%d", thr
);
420 if (omp_get_num_threads () == 5 && test_spread_master_close
)
421 /* Outer is spread, inner spread, innermost close. */
422 switch (places_array
[test_places
].count
)
424 /* All are T = 5, P = 1. */
426 p
= places_array
[test_places
].places
[7];
429 p
= places_array
[test_places
].places
[6];
432 p
= places_array
[test_places
].places
[4];
435 p
= places_array
[test_places
].places
[0];
438 p
= places_array
[test_places
].places
[1];
447 /* True/spread, master. */
448 #pragma omp parallel num_threads (4) proc_bind(master)
450 verify (omp_proc_bind_master
, omp_proc_bind_close
);
453 struct place p
= places_array
[0].places
[0];
454 int thr
= omp_get_thread_num ();
455 printf ("#1,#3 thread 3,%d", thr
);
456 if (omp_get_num_threads () == 4 && test_spread_master_close
)
457 /* Outer is spread, inner master, so just bind to the
458 place or the master thread, which is thr 3 above. */
459 switch (places_array
[test_places
].count
)
463 p
= places_array
[test_places
].places
[6];
466 p
= places_array
[test_places
].places
[4];
469 p
= places_array
[test_places
].places
[0];
472 p
= places_array
[test_places
].places
[1];
479 /* True/spread, close. */
480 #pragma omp parallel num_threads (6) proc_bind (close)
482 verify (omp_proc_bind_close
, omp_proc_bind_close
);
485 struct place p
= places_array
[0].places
[0];
486 int thr
= omp_get_thread_num ();
487 printf ("#1,#4 thread 3,%d", thr
);
488 if (omp_get_num_threads () == 6 && test_spread_master_close
)
489 /* Outer is spread, inner close. */
490 switch (places_array
[test_places
].count
)
493 /* T = 6, P = 2, unit sized subpartitions. */
494 p
= places_array
[test_places
].places
[6 + thr
/ 3];
496 /* The rest are T = 6, P = 1. */
498 p
= places_array
[test_places
].places
[6];
501 p
= places_array
[test_places
].places
[4];
504 p
= places_array
[test_places
].places
[0];
507 p
= places_array
[test_places
].places
[1];
518 #pragma omp parallel num_threads (5) proc_bind(spread)
520 verify (omp_proc_bind_spread
, omp_proc_bind_master
);
523 struct place p
= places_array
[0].places
[0];
524 int thr
= omp_get_thread_num ();
525 printf ("#2 thread %d", thr
);
526 if (omp_get_num_threads () == 5
527 && (test_spread_master_close
|| test_true
))
528 switch (places_array
[test_places
].count
)
531 /* T = 5, P = 8, first 3 subpartitions have 2 places, last
533 p
= places_array
[test_places
].places
[thr
< 3 ? 2 * thr
: 3 + thr
];
536 /* T = 5, P = 7, first 2 subpartitions have 2 places, last
538 p
= places_array
[test_places
].places
[thr
< 2 ? 2 * thr
: 2 + thr
];
541 /* T = 5, P = 5, unit sized subpartitions, each one with one
543 p
= places_array
[test_places
].places
[thr
];
546 /* T = 5, P = 3, unit sized subpartitions, first gets
547 thr0 and thr3, second thr1 and thr4, third thr2. */
548 p
= places_array
[test_places
].places
[thr
>= 3 ? thr
- 3 : thr
];
551 /* T = 5, P = 2, unit sized subpartitions, first with
552 thr{0,1,4} and second with thr{2,3}. */
553 p
= places_array
[test_places
].places
[thr
== 4 ? 0 : thr
/ 2];
560 if (omp_get_thread_num () == 3)
563 switch (places_array
[test_places
].count
)
565 case 8: pp
= 6; break;
566 case 7: pp
= 5; break;
567 case 5: pp
= 3; break;
568 case 2: pp
= 1; break;
570 /* Spread, spread/master. */
571 #pragma omp parallel num_threads (3) firstprivate (pp)
573 verify (omp_proc_bind_spread
, omp_proc_bind_close
);
576 struct place p
= places_array
[0].places
[0];
577 int thr
= omp_get_thread_num ();
578 printf ("#2,#1 thread 3,%d", thr
);
579 if (test_spread_master_close
|| test_true
)
580 /* Outer is spread, inner spread resp. master, bit we have
581 just unit sized partitions. */
582 p
= places_array
[test_places
].places
[pp
];
587 /* Spread, spread. */
588 #pragma omp parallel num_threads (5) proc_bind (spread) \
591 verify (omp_proc_bind_spread
, omp_proc_bind_close
);
594 struct place p
= places_array
[0].places
[0];
595 int thr
= omp_get_thread_num ();
596 printf ("#2,#2 thread 3,%d", thr
);
597 if (test_spread_master_close
|| test_true
)
598 /* Outer is spread, inner spread, bit we have
599 just unit sized partitions. */
600 p
= places_array
[test_places
].places
[pp
];
605 /* Spread, master. */
606 #pragma omp parallel num_threads (4) proc_bind(master) \
609 verify (omp_proc_bind_master
, omp_proc_bind_close
);
612 struct place p
= places_array
[0].places
[0];
613 int thr
= omp_get_thread_num ();
614 printf ("#2,#3 thread 3,%d", thr
);
615 if (test_spread_master_close
|| test_true
)
616 /* Outer is spread, inner master, bit we have
617 just unit sized partitions. */
618 p
= places_array
[test_places
].places
[pp
];
624 #pragma omp parallel num_threads (6) proc_bind (close) \
627 verify (omp_proc_bind_close
, omp_proc_bind_close
);
630 struct place p
= places_array
[0].places
[0];
631 int thr
= omp_get_thread_num ();
632 printf ("#2,#4 thread 3,%d", thr
);
633 if (test_spread_master_close
|| test_true
)
634 /* Outer is spread, inner close, bit we have
635 just unit sized partitions. */
636 p
= places_array
[test_places
].places
[pp
];
645 #pragma omp parallel num_threads (3) proc_bind(master)
647 verify (omp_proc_bind_master
, omp_proc_bind_master
);
650 struct place p
= places_array
[0].places
[0];
651 int thr
= omp_get_thread_num ();
652 printf ("#3 thread %d", thr
);
653 if (test_spread_master_close
|| test_true
)
654 p
= places_array
[test_places
].places
[0];
659 if (omp_get_thread_num () == 2)
661 /* Master, master. */
662 #pragma omp parallel num_threads (4)
664 verify (omp_proc_bind_master
, omp_proc_bind_close
);
667 struct place p
= places_array
[0].places
[0];
668 int thr
= omp_get_thread_num ();
669 printf ("#3,#1 thread 2,%d", thr
);
670 if (test_spread_master_close
|| test_true
)
671 /* Outer is master, inner is master. */
672 p
= places_array
[test_places
].places
[0];
677 /* Master, spread. */
678 #pragma omp parallel num_threads (4) proc_bind (spread)
680 verify (omp_proc_bind_spread
, omp_proc_bind_close
);
683 struct place p
= places_array
[0].places
[0];
684 int thr
= omp_get_thread_num ();
685 printf ("#3,#2 thread 2,%d", thr
);
686 if (omp_get_num_threads () == 4
687 && (test_spread_master_close
|| test_true
))
688 /* Outer is master, inner is spread. */
689 switch (places_array
[test_places
].count
)
692 /* T = 4, P = 8, each subpartition has 2 places. */
694 /* T = 4, P = 7, each subpartition has 2 places, but
695 last partition, which has just one place. */
696 p
= places_array
[test_places
].places
[2 * thr
];
699 /* T = 4, P = 5, first subpartition has 2 places, the
701 p
= places_array
[test_places
].places
[thr
? 1 + thr
: 0];
704 /* T = 4, P = 3, unit sized subpartitions, first gets
705 thr0 and thr3, second thr1, third thr2. */
706 p
= places_array
[test_places
].places
[thr
== 3 ? 0 : thr
];
709 /* T = 4, P = 2, unit sized subpartitions, each with
711 p
= places_array
[test_places
].places
[thr
/ 2];
718 if (omp_get_thread_num () == 0)
720 /* Master, spread, close. */
721 #pragma omp parallel num_threads (5) proc_bind (close)
723 verify (omp_proc_bind_close
, omp_proc_bind_close
);
726 struct place p
= places_array
[0].places
[0];
727 int thr
= omp_get_thread_num ();
728 printf ("#3,#2,#1 thread 2,0,%d", thr
);
729 if (omp_get_num_threads () == 5
730 && (test_spread_master_close
|| test_true
))
731 /* Outer is master, inner spread, innermost close. */
732 switch (places_array
[test_places
].count
)
734 /* First 3 are T = 5, P = 2. */
738 p
= places_array
[test_places
].places
[(thr
& 2) / 2];
740 /* All the rest are T = 5, P = 1. */
743 p
= places_array
[test_places
].places
[0];
752 if (omp_get_thread_num () == 3)
754 /* Master, spread, close. */
755 #pragma omp parallel num_threads (5) proc_bind (close)
757 verify (omp_proc_bind_close
, omp_proc_bind_close
);
760 struct place p
= places_array
[0].places
[0];
761 int thr
= omp_get_thread_num ();
762 printf ("#3,#2,#2 thread 2,3,%d", thr
);
763 if (omp_get_num_threads () == 5
764 && (test_spread_master_close
|| test_true
))
765 /* Outer is master, inner spread, innermost close. */
766 switch (places_array
[test_places
].count
)
770 p
= places_array
[test_places
].places
[6
773 /* All the rest are T = 5, P = 1. */
775 p
= places_array
[test_places
].places
[6];
778 p
= places_array
[test_places
].places
[4];
781 p
= places_array
[test_places
].places
[0];
784 p
= places_array
[test_places
].places
[1];
793 /* Master, master. */
794 #pragma omp parallel num_threads (4) proc_bind(master)
796 verify (omp_proc_bind_master
, omp_proc_bind_close
);
799 struct place p
= places_array
[0].places
[0];
800 int thr
= omp_get_thread_num ();
801 printf ("#3,#3 thread 2,%d", thr
);
802 if (test_spread_master_close
|| test_true
)
803 /* Outer is master, inner master. */
804 p
= places_array
[test_places
].places
[0];
810 #pragma omp parallel num_threads (6) proc_bind (close)
812 verify (omp_proc_bind_close
, omp_proc_bind_close
);
815 struct place p
= places_array
[0].places
[0];
816 int thr
= omp_get_thread_num ();
817 printf ("#3,#4 thread 2,%d", thr
);
818 if (omp_get_num_threads () == 6
819 && (test_spread_master_close
|| test_true
))
820 switch (places_array
[test_places
].count
)
826 p
= places_array
[test_places
].places
[thr
];
829 /* T = 6, P = 5. thr{0,5} go into the first place. */
830 p
= places_array
[test_places
].places
[thr
== 5 ? 0 : thr
];
833 /* T = 6, P = 3, two threads into each place. */
834 p
= places_array
[test_places
].places
[thr
/ 2];
837 /* T = 6, P = 2, 3 threads into each place. */
838 p
= places_array
[test_places
].places
[thr
/ 3];
848 #pragma omp parallel num_threads (5) proc_bind(close)
850 verify (omp_proc_bind_close
, omp_proc_bind_master
);
853 struct place p
= places_array
[0].places
[0];
854 int thr
= omp_get_thread_num ();
855 printf ("#4 thread %d", thr
);
856 if (omp_get_num_threads () == 5
857 && (test_spread_master_close
|| test_true
))
858 switch (places_array
[test_places
].count
)
866 p
= places_array
[test_places
].places
[thr
];
869 /* T = 5, P = 3, thr{0,3} in first place, thr{1,4} in second,
871 p
= places_array
[test_places
].places
[thr
>= 3 ? thr
- 3 : thr
];
874 /* T = 5, P = 2, thr{0,1,4} in first place, thr{2,3} in second. */
875 p
= places_array
[test_places
].places
[thr
== 4 ? 0 : thr
/ 2];
882 if (omp_get_thread_num () == 2)
885 switch (places_array
[test_places
].count
)
897 /* Close, close/master. */
898 #pragma omp parallel num_threads (4) firstprivate (pp)
900 verify (omp_proc_bind_close
, omp_proc_bind_close
);
903 struct place p
= places_array
[0].places
[0];
904 int thr
= omp_get_thread_num ();
905 printf ("#4,#1 thread 2,%d", thr
);
906 if (test_spread_master_close
)
907 /* Outer is close, inner is master. */
908 p
= places_array
[test_places
].places
[pp
];
909 else if (omp_get_num_threads () == 4 && test_true
)
910 /* Outer is close, inner is close. */
911 switch (places_array
[test_places
].count
)
917 p
= places_array
[test_places
].places
[2 + thr
];
920 /* T = 4, P = 5. There is wrap-around for thr3. */
921 p
= places_array
[test_places
].places
[thr
== 3 ? 0 : 2 + thr
];
924 /* T = 4, P = 3, thr{0,3} go into p2, thr1 into p0, thr2
926 p
= places_array
[test_places
].places
[(2 + thr
) % 3];
929 /* T = 4, P = 2, 2 threads into each place. */
930 p
= places_array
[test_places
].places
[1 - thr
/ 2];
939 #pragma omp parallel num_threads (4) proc_bind (spread)
941 verify (omp_proc_bind_spread
, omp_proc_bind_close
);
944 struct place p
= places_array
[0].places
[0];
945 int thr
= omp_get_thread_num ();
946 printf ("#4,#2 thread 2,%d", thr
);
947 if (omp_get_num_threads () == 4
948 && (test_spread_master_close
|| test_true
))
949 /* Outer is close, inner is spread. */
950 switch (places_array
[test_places
].count
)
953 /* T = 4, P = 8, each subpartition has 2 places. */
955 /* T = 4, P = 7, each subpartition has 2 places, but
956 last partition, which has just one place. */
957 p
= places_array
[test_places
].places
[thr
== 3 ? 0
961 /* T = 4, P = 5, first subpartition has 2 places, the
963 p
= places_array
[test_places
].places
[thr
== 3 ? 0
967 /* T = 4, P = 3, unit sized subpartitions, third gets
968 thr0 and thr3, first thr1, second thr2. */
969 p
= places_array
[test_places
].places
[thr
== 0 ? 2 : thr
- 1];
972 /* T = 4, P = 2, unit sized subpartitions, each with
974 p
= places_array
[test_places
].places
[1 - thr
/ 2];
981 if (omp_get_thread_num () == 0)
983 /* Close, spread, close. */
984 #pragma omp parallel num_threads (5) proc_bind (close)
986 verify (omp_proc_bind_close
, omp_proc_bind_close
);
989 struct place p
= places_array
[0].places
[0];
990 int thr
= omp_get_thread_num ();
991 printf ("#4,#2,#1 thread 2,0,%d", thr
);
992 if (omp_get_num_threads () == 5
993 && (test_spread_master_close
|| test_true
))
994 /* Outer is close, inner spread, innermost close. */
995 switch (places_array
[test_places
].count
)
1000 p
= places_array
[test_places
].places
[2
1003 /* All the rest are T = 5, P = 1. */
1006 p
= places_array
[test_places
].places
[2];
1009 p
= places_array
[test_places
].places
[1];
1018 if (omp_get_thread_num () == 2)
1020 /* Close, spread, close. */
1021 #pragma omp parallel num_threads (5) proc_bind (close)
1023 verify (omp_proc_bind_close
, omp_proc_bind_close
);
1024 #pragma omp critical
1026 struct place p
= places_array
[0].places
[0];
1027 int thr
= omp_get_thread_num ();
1028 printf ("#4,#2,#2 thread 2,2,%d", thr
);
1029 if (omp_get_num_threads () == 5
1030 && (test_spread_master_close
|| test_true
))
1031 /* Outer is close, inner spread, innermost close. */
1032 switch (places_array
[test_places
].count
)
1036 p
= places_array
[test_places
].places
[6
1039 /* All the rest are T = 5, P = 1. */
1041 p
= places_array
[test_places
].places
[6];
1044 p
= places_array
[test_places
].places
[4];
1047 p
= places_array
[test_places
].places
[1];
1050 p
= places_array
[test_places
].places
[0];
1059 if (omp_get_thread_num () == 3)
1061 /* Close, spread, close. */
1062 #pragma omp parallel num_threads (5) proc_bind (close)
1064 verify (omp_proc_bind_close
, omp_proc_bind_close
);
1065 #pragma omp critical
1067 struct place p
= places_array
[0].places
[0];
1068 int thr
= omp_get_thread_num ();
1069 printf ("#4,#2,#3 thread 2,3,%d", thr
);
1070 if (omp_get_num_threads () == 5
1071 && (test_spread_master_close
|| test_true
))
1072 /* Outer is close, inner spread, innermost close. */
1073 switch (places_array
[test_places
].count
)
1079 p
= places_array
[test_places
].places
[(thr
& 2) / 2];
1081 /* All the rest are T = 5, P = 1. */
1083 p
= places_array
[test_places
].places
[2];
1086 p
= places_array
[test_places
].places
[0];
1095 /* Close, master. */
1096 #pragma omp parallel num_threads (4) proc_bind(master) \
1099 verify (omp_proc_bind_master
, omp_proc_bind_close
);
1100 #pragma omp critical
1102 struct place p
= places_array
[0].places
[0];
1103 int thr
= omp_get_thread_num ();
1104 printf ("#4,#3 thread 2,%d", thr
);
1105 if (test_spread_master_close
|| test_true
)
1106 /* Outer is close, inner master. */
1107 p
= places_array
[test_places
].places
[pp
];
1113 #pragma omp parallel num_threads (6) proc_bind (close)
1115 verify (omp_proc_bind_close
, omp_proc_bind_close
);
1116 #pragma omp critical
1118 struct place p
= places_array
[0].places
[0];
1119 int thr
= omp_get_thread_num ();
1120 printf ("#4,#4 thread 2,%d", thr
);
1121 if (omp_get_num_threads () == 6
1122 && (test_spread_master_close
|| test_true
))
1123 switch (places_array
[test_places
].count
)
1127 p
= places_array
[test_places
].places
[2 + thr
];
1131 p
= places_array
[test_places
].places
[thr
== 5 ? 0 : 2 + thr
];
1134 /* T = 6, P = 5. thr{0,5} go into the third place. */
1135 p
= places_array
[test_places
].places
[thr
>= 3 ? thr
- 3
1139 /* T = 6, P = 3, two threads into each place. */
1140 p
= places_array
[test_places
].places
[thr
< 2 ? 2
1144 /* T = 6, P = 2, 3 threads into each place. */
1145 p
= places_array
[test_places
].places
[1 - thr
/ 3];