xref: /llvm-project/openmp/runtime/test/affinity/teams-affinity.c (revision 50b68a3d030543daf97794d68682cc698964ca26)
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 
set_default_max_nteams()31 static void set_default_max_nteams() {
32   // Do not overwrite if already in environment
33   setenv("KMP_TEAMS_THREAD_LIMIT", STR(MAX_NTEAMS), 0);
34 }
35 
get_max_nteams()36 static int get_max_nteams() {
37   int max_nteams;
38   const char *value = getenv("KMP_TEAMS_THREAD_LIMIT");
39   if (!value) {
40     fprintf(stderr, "KMP_TEAMS_THREAD_LIMIT must be set!\n");
41     exit(EXIT_FAILURE);
42   }
43   max_nteams = atoi(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
get_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("KMP_TEAMS_PROC_BIND");
56   if (value) {
57     if (strcmp(value, "spread") == 0) {
58       proc_bind = omp_proc_bind_spread;
59     } else if (strcmp(value, "close") == 0) {
60       proc_bind = omp_proc_bind_close;
61     } else if (strcmp(value, "primary") == 0 || strcmp(value, "master") == 0) {
62       proc_bind = omp_proc_bind_master;
63     } else {
64       fprintf(stderr,
65               "KMP_TEAMS_PROC_BIND should be one of spread, close, primary");
66       exit(EXIT_FAILURE);
67     }
68   }
69   return proc_bind;
70 }
71 
main(int argc,char ** argv)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(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(teams_places[i]);
113     }
114   }
115 
116   free(teams_places);
117   topology_free_places(place_list);
118   return EXIT_SUCCESS;
119 }
120