diff options
Diffstat (limited to 'final/runtime/test/affinity/format/affinity_values.c')
-rw-r--r-- | final/runtime/test/affinity/format/affinity_values.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/final/runtime/test/affinity/format/affinity_values.c b/final/runtime/test/affinity/format/affinity_values.c new file mode 100644 index 0000000..37ab210 --- /dev/null +++ b/final/runtime/test/affinity/format/affinity_values.c @@ -0,0 +1,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; +} |