/* Check that the nteams ICV is honored. */ /* PR libgomp/109875 */ /* This base version of testcases is supposed to be run with all OMP_NUM_TEAMS* env vars being unset. The variants teams-nteams-icv-{2,3,4}.c test it by setting the various OMP_NUM_TEAMS* env vars and #define MY_... for checking. Currently, only 0,1,2 is supported for the envar via #define and with remote execution, dg-set-target-env-var does not work with DejaGNU, hence, gcc/testsuite/lib/gcc-dg.exp marks those tests as UNSUPPORTED. */ #define MY_MAX_DEVICES 3 /* OpenMP currently has: - nteams-var ICV is initialized to 0; one ICV per device - OMP_NUM_TEAMS(_DEV(_)) overrides it OMP_NUM_TEAMS_ALL overrides it - Number of teams is: -> the value specific by num_teams([lower:]upper) with lower := upper if unspecified -> Otherwise, if nteams-var ICV > 0, #teams <= nteams-var ICV -> Otherwise, if nteams-var ICV <= 0, #teams > 1 GCC uses 3 as default on the host and 1 for host fallback. For offloading, it is device specific >> 1. */ #include int main () { int num_teams_env = -1, num_teams_env_dev = -1; int num_teams_env_devs[MY_MAX_DEVICES]; #ifdef MY_OMP_NUM_TEAMS_ALL num_teams_env = num_teams_env_dev = MY_OMP_NUM_TEAMS_ALL; #endif #ifdef MY_OMP_NUM_TEAMS num_teams_env = MY_OMP_NUM_TEAMS; #endif #ifdef MY_OMP_NUM_TEAMS_DEV num_teams_env_dev = MY_OMP_NUM_TEAMS_DEV; #endif #if MY_MAX_DEVICES != 3 #error "Currently strictly assuming MY_MAX_DEVICES = 3" #endif #if defined(MY_OMP_NUM_TEAMS_DEV_4) || defined(MY_OMP_NUM_TEAMS_DEV_5) #error "Currently strictly assuming MY_MAX_DEVICES = 3" #endif #ifdef MY_OMP_NUM_TEAMS_DEV_0 num_teams_env_devs[0] = MY_OMP_NUM_TEAMS_DEV_0; #else num_teams_env_devs[0] = num_teams_env_dev; #endif #ifdef MY_OMP_NUM_TEAMS_DEV_1 num_teams_env_devs[1] = MY_OMP_NUM_TEAMS_DEV_1; #else num_teams_env_devs[1] = num_teams_env_dev; #endif #ifdef MY_OMP_NUM_TEAMS_DEV_2 num_teams_env_devs[2] = MY_OMP_NUM_TEAMS_DEV_2; #else num_teams_env_devs[2] = num_teams_env_dev; #endif /* Check that the number of teams (initial device and in target) is >= 1 and, if omp_get_max_teams() > 0, it does not exceed omp_get_max_teams (). */ int nteams, num_teams; /* Assume that omp_get_max_teams (); returns the ICV, i.e. 0 as default init and not the number of teams that would be run; hence: '>='. */ nteams = omp_get_max_teams (); if (nteams < 0 || (num_teams_env >= 0 && nteams != num_teams_env)) __builtin_abort (); num_teams = -1; #pragma omp teams if (omp_get_team_num () == 0) num_teams = omp_get_num_teams (); if (num_teams < 1 || (nteams > 0 && num_teams > nteams)) __builtin_abort (); /* GCC hard codes 3 teams - check for it. */ if (nteams <= 0 && num_teams != 3) __builtin_abort (); /* For each device, including host fallback. */ for (int dev = 0; dev <= omp_get_num_devices (); dev++) { int num_teams_icv = num_teams_env_dev; if (dev == omp_get_num_devices ()) num_teams_icv = num_teams_env; else if (dev < MY_MAX_DEVICES) num_teams_icv = num_teams_env_devs[dev]; nteams = -1; #pragma omp target device(dev) map(from: nteams) nteams = omp_get_max_teams (); if (nteams < 0 || (num_teams_icv >= 0 && nteams != num_teams_icv)) __builtin_abort (); num_teams = -1; #pragma omp target teams device(dev) map(from: num_teams) if (omp_get_team_num () == 0) num_teams = omp_get_num_teams (); if (num_teams < 1 || (nteams > 0 && num_teams > nteams)) __builtin_abort (); /* GCC hard codes 1 team for host fallback - check for it. */ if (dev == omp_get_num_devices () && num_teams != 1) __builtin_abort (); } /* Now set the nteams-var ICV and check that omp_get_max_teams() returns the set value and that the following holds: num_teams >= 1 and num_teams <= nteams-var ICV. Additionally, implementation defined, assume: - num_teams == (not '<=') nteams-var ICV, except: - num_teams == 1 for host fallback. */ omp_set_num_teams (5); nteams = omp_get_max_teams (); if (nteams != 5) __builtin_abort (); num_teams = -1; #pragma omp teams if (omp_get_team_num () == 0) num_teams = omp_get_num_teams (); if (num_teams != 5) __builtin_abort (); /* For each device, including host fallback. */ for (int dev = 0; dev <= omp_get_num_devices (); dev++) { #pragma omp target device(dev) firstprivate(dev) omp_set_num_teams (7 + dev); #pragma omp target device(dev) map(from: nteams) nteams = omp_get_max_teams (); if (nteams != 7 + dev) __builtin_abort (); num_teams = -1; #pragma omp target teams device(dev) map(from: num_teams) if (omp_get_team_num () == 0) num_teams = omp_get_num_teams (); if (dev == omp_get_num_devices ()) { if (num_teams != 1) __builtin_abort (); } else { if (num_teams != 7 + dev) __builtin_abort (); } } /* Now use the num_teams clause explicitly. */ num_teams = -1; #pragma omp teams num_teams(6) if (omp_get_team_num () == 0) num_teams = omp_get_num_teams (); if (num_teams != 6) __builtin_abort (); /* For each device, including host fallback. */ for (int dev = 0; dev <= omp_get_num_devices (); dev++) { num_teams = -1; #pragma omp target teams device(dev) map(from: num_teams) num_teams(dev+3) if (omp_get_team_num () == 0) num_teams = omp_get_num_teams (); /* This must match the set value, also with host fallback. */ if (num_teams != 3 + dev) __builtin_abort (); } return 0; }