1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#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 <stdarg.h>
#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;
}
|