brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 37ab210 Raw
136 lines · c
1// RUN: %libomp-compile2// RUN: env OMP_PROC_BIND=close OMP_PLACES=threads %libomp-run3// RUN: env OMP_PROC_BIND=close OMP_PLACES=cores %libomp-run4// RUN: env OMP_PROC_BIND=close OMP_PLACES=sockets %libomp-run5// RUN: env KMP_AFFINITY=compact %libomp-run6// RUN: env KMP_AFFINITY=scatter %libomp-run7// REQUIRES: affinity8 9#include <stdio.h>10#include <stdlib.h>11#include <string.h>12#include <omp.h>13 14#define XSTR(x) #x15#define STR(x) XSTR(x)16 17#define streqls(s1, s2) (!strcmp(s1, s2))18 19#define check(condition)                                                       \20  if (!(condition)) {                                                          \21    fprintf(stderr, "error: %s: %d: " STR(condition) "\n", __FILE__,           \22            __LINE__);                                                         \23    exit(1);                                                                   \24  }25 26#define DEBUG 027 28#if DEBUG29#include <stdarg.h>30#endif31 32#define BUFFER_SIZE 102433 34char buf[BUFFER_SIZE];35#pragma omp threadprivate(buf)36 37static int debug_printf(const char* format, ...) {38  int retval = 0;39#if DEBUG40  va_list args;41  va_start(args, format);42  retval = vprintf(format, args);43  va_end(args);44#endif45  return retval;46}47 48static void display_affinity_environment() {49#if DEBUG50  printf("Affinity Environment:\n");51  printf("  OMP_PROC_BIND=%s\n", getenv("OMP_PROC_BIND"));52  printf("  OMP_PLACES=%s\n", getenv("OMP_PLACES"));53  printf("  KMP_AFFINITY=%s\n", getenv("KMP_AFFINITY"));54#endif55}56 57// Reads in a list of integers into ids array (not going past ids_size)58// e.g., if affinity = "0-4,6,8-10,14,16,17-20,23"59//       then ids = [0,1,2,3,4,6,8,9,10,14,16,17,18,19,20,23]60void list_to_ids(const char* affinity, int* ids, int ids_size) {61  int id, b, e, ids_index;62  char *aff, *begin, *end, *absolute_end;63  aff = strdup(affinity);64  absolute_end = aff + strlen(aff);65  ids_index = 0;66  begin = end = aff;67  while (end < absolute_end) {68    end = begin;69    while (*end != '\0' && *end != ',')70      end++;71    *end = '\0';72    if (strchr(begin, '-') != NULL) {73      // Range74      sscanf(begin, "%d-%d", &b, &e);75    } else {76      // Single Number77      sscanf(begin, "%d", &b);78      e = b;79    }80    for (id = b; id <= e; ++id) {81      ids[ids_index++] = id;82      if (ids_index >= ids_size) {83        free(aff);84        return;85      }86    }87    begin = end + 1;88  }89  free(aff);90}91 92void check_thread_affinity() {93  int i;94  const char *formats[2] = {"%{thread_affinity}", "%A"};95  for (i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) {96    omp_set_affinity_format(formats[i]);97    #pragma omp parallel98    {99      int j, k;100      int place = omp_get_place_num();101      int num_procs = omp_get_place_num_procs(place);102      int *ids = (int *)malloc(sizeof(int) * num_procs);103      int *ids2 = (int *)malloc(sizeof(int) * num_procs);104      char buf[256];105      size_t n = omp_capture_affinity(buf, 256, NULL);106      check(n <= 256);107      omp_get_place_proc_ids(place, ids);108      list_to_ids(buf, ids2, num_procs);109 110      #pragma omp for schedule(static) ordered111      for (k = 0; k < omp_get_num_threads(); ++k) {112        #pragma omp ordered113        {114          debug_printf("Thread %d: captured affinity = %s\n",115                       omp_get_thread_num(), buf);116          for (j = 0; j < num_procs; ++j) {117            debug_printf("Thread %d: ids[%d] = %d ids2[%d] = %d\n",118                         omp_get_thread_num(), j, ids[j], j, ids2[j]);119            check(ids[j] == ids2[j]);120          }121        }122      }123 124      free(ids);125      free(ids2);126    }127  }128}129 130int main(int argc, char** argv) {131  omp_set_nested(1);132  display_affinity_environment();133  check_thread_affinity();134  return 0;135}136