1 | // RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 %libomp-run |
2 | // RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_HOT_TEAMS_MAX_LEVEL=2 %libomp-run |
3 | // RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_TEAMS_PROC_BIND=close %libomp-run |
4 | // RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_TEAMS_PROC_BIND=close KMP_HOT_TEAMS_MAX_LEVEL=2 %libomp-run |
5 | // RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_TEAMS_PROC_BIND=primary %libomp-run |
6 | // RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_TEAMS_PROC_BIND=primary KMP_HOT_TEAMS_MAX_LEVEL=2 %libomp-run |
7 | // REQUIRES: linux |
8 | // UNSUPPORTED: clang-5, clang-6, clang-7, clang-8, clang-9, clang-10 |
9 | // UNSUPPORTED: gcc-5, gcc-6, gcc-7, gcc-8 |
10 | // UNSUPPORTED: icc |
11 | // |
12 | // KMP_TEAMS_THREAD_LIMIT limits the number of total teams |
13 | // OMP_TEAMS_THREAD_LIMIT limits the number of threads per team |
14 | |
15 | #ifndef _GNU_SOURCE |
16 | #define _GNU_SOURCE |
17 | #endif |
18 | #include <stdio.h> |
19 | #include <stdlib.h> |
20 | #include <string.h> |
21 | #include "libomp_test_affinity.h" |
22 | #include "libomp_test_topology.h" |
23 | |
24 | #define _STR(X) #X |
25 | #define STR(X) _STR(X) |
26 | |
27 | #ifndef MAX_NTEAMS |
28 | #define MAX_NTEAMS 256 |
29 | #endif |
30 | |
31 | static void set_default_max_nteams() { |
32 | // Do not overwrite if already in environment |
33 | setenv(name: "KMP_TEAMS_THREAD_LIMIT" , STR(MAX_NTEAMS), replace: 0); |
34 | } |
35 | |
36 | static int get_max_nteams() { |
37 | int max_nteams; |
38 | const char *value = getenv(name: "KMP_TEAMS_THREAD_LIMIT" ); |
39 | if (!value) { |
40 | fprintf(stderr, format: "KMP_TEAMS_THREAD_LIMIT must be set!\n" ); |
41 | exit(EXIT_FAILURE); |
42 | } |
43 | max_nteams = atoi(nptr: value); |
44 | if (max_nteams <= 0) |
45 | max_nteams = 1; |
46 | if (max_nteams > MAX_NTEAMS) |
47 | max_nteams = MAX_NTEAMS; |
48 | return max_nteams; |
49 | } |
50 | |
51 | // Return the value in KMP_TEAMS_PROC_BIND |
52 | static omp_proc_bind_t get_teams_proc_bind() { |
53 | // defaults to spread |
54 | omp_proc_bind_t proc_bind = omp_proc_bind_spread; |
55 | const char *value = getenv(name: "KMP_TEAMS_PROC_BIND" ); |
56 | if (value) { |
57 | if (strcmp(s1: value, s2: "spread" ) == 0) { |
58 | proc_bind = omp_proc_bind_spread; |
59 | } else if (strcmp(s1: value, s2: "close" ) == 0) { |
60 | proc_bind = omp_proc_bind_close; |
61 | } else if (strcmp(s1: value, s2: "primary" ) == 0 || strcmp(s1: value, s2: "master" ) == 0) { |
62 | proc_bind = omp_proc_bind_master; |
63 | } else { |
64 | fprintf(stderr, |
65 | format: "KMP_TEAMS_PROC_BIND should be one of spread, close, primary" ); |
66 | exit(EXIT_FAILURE); |
67 | } |
68 | } |
69 | return proc_bind; |
70 | } |
71 | |
72 | int main(int argc, char **argv) { |
73 | int i, nteams, max_nteams, factor; |
74 | place_list_t **teams_places; |
75 | place_list_t *place_list; |
76 | omp_proc_bind_t teams_proc_bind; |
77 | |
78 | // Set a default for the max number of teams if it is not already set |
79 | set_default_max_nteams(); |
80 | place_list = topology_alloc_openmp_places(); |
81 | max_nteams = get_max_nteams(); |
82 | // Further limit the number of teams twice the number of OMP_PLACES |
83 | if (max_nteams > 2 * place_list->num_places) |
84 | max_nteams = 2 * place_list->num_places; |
85 | teams_places = (place_list_t **)malloc(size: sizeof(place_list_t *) * max_nteams); |
86 | for (i = 0; i < max_nteams; ++i) |
87 | teams_places[i] = NULL; |
88 | teams_proc_bind = get_teams_proc_bind(); |
89 | |
90 | // factor inversely controls the number of test cases. |
91 | // the larger the factor, the more test cases will be performed. |
92 | if (teams_proc_bind == omp_proc_bind_master) { |
93 | factor = 2; |
94 | } else { |
95 | factor = 8; |
96 | } |
97 | |
98 | for (nteams = 1; nteams <= max_nteams; |
99 | nteams = nteams * factor / (factor - 1) + 1) { |
100 | // Check the same value twice to make sure hot teams are ok |
101 | int j; |
102 | for (j = 0; j < 2; ++j) { |
103 | // Gather the proc bind partitions from each team |
104 | #pragma omp teams num_teams(nteams) |
105 | teams_places[omp_get_team_num()] = topology_alloc_openmp_partition(); |
106 | |
107 | // Check all the partitions with the parent partition |
108 | proc_bind_check(teams_proc_bind, place_list, teams_places, nteams); |
109 | |
110 | // Free the proc bind partitions |
111 | for (i = 0; i < nteams; ++i) |
112 | topology_free_places(places: teams_places[i]); |
113 | } |
114 | } |
115 | |
116 | free(ptr: teams_places); |
117 | topology_free_places(places: place_list); |
118 | return EXIT_SUCCESS; |
119 | } |
120 | |