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
31static 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
36static 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
52static 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
72int 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

source code of openmp/runtime/test/affinity/teams-affinity.c