// RUN: %libomp-compile // RUN: env OMP_PROC_BIND=close OMP_PLACES=threads %libomp-run // RUN: env OMP_PROC_BIND=close OMP_PLACES=cores %libomp-run // RUN: env OMP_PROC_BIND=close OMP_PLACES=sockets %libomp-run // RUN: env KMP_AFFINITY=compact %libomp-run // RUN: env KMP_AFFINITY=scatter %libomp-run // REQUIRES: affinity #include #include #include #include #define XSTR(x) #x #define STR(x) XSTR(x) #define streqls(s1, s2) (!strcmp(s1, s2)) #define check(condition) \ if (!(condition)) { \ fprintf(stderr, "error: %s: %d: " STR(condition) "\n", __FILE__, \ __LINE__); \ exit(1); \ } #define DEBUG 0 #if DEBUG #include #endif #define BUFFER_SIZE 1024 char buf[BUFFER_SIZE]; #pragma omp threadprivate(buf) static int debug_printf(const char* format, ...) { int retval = 0; #if DEBUG va_list args; va_start(args, format); retval = vprintf(format, args); va_end(args); #endif return retval; } static void display_affinity_environment() { #if DEBUG printf("Affinity Environment:\n"); printf(" OMP_PROC_BIND=%s\n", getenv("OMP_PROC_BIND")); printf(" OMP_PLACES=%s\n", getenv("OMP_PLACES")); printf(" KMP_AFFINITY=%s\n", getenv("KMP_AFFINITY")); #endif } // Reads in a list of integers into ids array (not going past ids_size) // e.g., if affinity = "0-4,6,8-10,14,16,17-20,23" // then ids = [0,1,2,3,4,6,8,9,10,14,16,17,18,19,20,23] void list_to_ids(const char* affinity, int* ids, int ids_size) { int id, b, e, ids_index; char *aff, *begin, *end, *absolute_end; aff = strdup(affinity); absolute_end = aff + strlen(aff); ids_index = 0; begin = end = aff; while (end < absolute_end) { end = begin; while (*end != '\0' && *end != ',') end++; *end = '\0'; if (strchr(begin, '-') != NULL) { // Range sscanf(begin, "%d-%d", &b, &e); } else { // Single Number sscanf(begin, "%d", &b); e = b; } for (id = b; id <= e; ++id) { ids[ids_index++] = id; if (ids_index >= ids_size) { free(aff); return; } } begin = end + 1; } free(aff); } void check_thread_affinity() { int i; const char *formats[2] = {"%{thread_affinity}", "%A"}; for (i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) { omp_set_affinity_format(formats[i]); #pragma omp parallel { int j, k; int place = omp_get_place_num(); int num_procs = omp_get_place_num_procs(place); int *ids = (int *)malloc(sizeof(int) * num_procs); int *ids2 = (int *)malloc(sizeof(int) * num_procs); char buf[256]; size_t n = omp_capture_affinity(buf, 256, NULL); check(n <= 256); omp_get_place_proc_ids(place, ids); list_to_ids(buf, ids2, num_procs); #pragma omp for schedule(static) ordered for (k = 0; k < omp_get_num_threads(); ++k) { #pragma omp ordered { debug_printf("Thread %d: captured affinity = %s\n", omp_get_thread_num(), buf); for (j = 0; j < num_procs; ++j) { debug_printf("Thread %d: ids[%d] = %d ids2[%d] = %d\n", omp_get_thread_num(), j, ids[j], j, ids2[j]); check(ids[j] == ids2[j]); } } } free(ids); free(ids2); } } } int main(int argc, char** argv) { omp_set_nested(1); display_affinity_environment(); check_thread_affinity(); return 0; }