120 lines · c
1// RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 %libomp-run2// RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_HOT_TEAMS_MAX_LEVEL=2 %libomp-run3// RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_TEAMS_PROC_BIND=close %libomp-run4// 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-run5// RUN: %libomp-compile && env OMP_PLACES=cores OMP_TEAMS_THREAD_LIMIT=1 KMP_TEAMS_THREAD_LIMIT=256 KMP_TEAMS_PROC_BIND=primary %libomp-run6// 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-run7// REQUIRES: linux8// UNSUPPORTED: clang-5, clang-6, clang-7, clang-8, clang-9, clang-109// UNSUPPORTED: gcc-5, gcc-6, gcc-7, gcc-810// UNSUPPORTED: icc11//12// KMP_TEAMS_THREAD_LIMIT limits the number of total teams13// OMP_TEAMS_THREAD_LIMIT limits the number of threads per team14 15#ifndef _GNU_SOURCE16#define _GNU_SOURCE17#endif18#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) #X25#define STR(X) _STR(X)26 27#ifndef MAX_NTEAMS28#define MAX_NTEAMS 25629#endif30 31static void set_default_max_nteams() {32 // Do not overwrite if already in environment33 setenv("KMP_TEAMS_THREAD_LIMIT", STR(MAX_NTEAMS), 0);34}35 36static 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_BIND52static omp_proc_bind_t get_teams_proc_bind() {53 // defaults to spread54 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 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 set79 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_PLACES83 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 ok101 int j;102 for (j = 0; j < 2; ++j) {103 // Gather the proc bind partitions from each team104 #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 partition108 proc_bind_check(teams_proc_bind, place_list, teams_places, nteams);109 110 // Free the proc bind partitions111 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