[Openmp-commits] [openmp] r349411 - [OpenMP] Add affinity format tests

Jonathan Peyton via Openmp-commits openmp-commits at lists.llvm.org
Mon Dec 17 14:33:22 PST 2018


Author: jlpeyton
Date: Mon Dec 17 14:33:21 2018
New Revision: 349411

URL: http://llvm.org/viewvc/llvm-project?rev=349411&view=rev
Log:
[OpenMP] Add affinity format tests


Added:
    openmp/trunk/runtime/test/affinity/
    openmp/trunk/runtime/test/affinity/format/
    openmp/trunk/runtime/test/affinity/format/affinity_display.1.c
    openmp/trunk/runtime/test/affinity/format/affinity_values.c
    openmp/trunk/runtime/test/affinity/format/api.c
    openmp/trunk/runtime/test/affinity/format/api2.c
    openmp/trunk/runtime/test/affinity/format/check.py
    openmp/trunk/runtime/test/affinity/format/fields_modifiers.c
    openmp/trunk/runtime/test/affinity/format/fields_values.c
    openmp/trunk/runtime/test/affinity/format/increase.c
    openmp/trunk/runtime/test/affinity/format/nested.c
    openmp/trunk/runtime/test/affinity/format/nested2.c
    openmp/trunk/runtime/test/affinity/format/nested_mixed.c
    openmp/trunk/runtime/test/affinity/format/nested_serial.c
    openmp/trunk/runtime/test/affinity/format/proc_bind.c
    openmp/trunk/runtime/test/affinity/format/simple.c
    openmp/trunk/runtime/test/affinity/format/simple_env.c

Added: openmp/trunk/runtime/test/affinity/format/affinity_display.1.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/affinity_display.1.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/affinity_display.1.c (added)
+++ openmp/trunk/runtime/test/affinity/format/affinity_display.1.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,92 @@
+// RUN: %libomp-compile
+// RUN: env OMP_DISPLAY_AFFINITY=TRUE OMP_NUM_THREADS=4 OMP_PLACES='{0,1},{2,3},{4,5},{6,7}' %libomp-run | python %S/check.py -c 'CHECK' %s
+
+// Affinity Display examples
+#include <stdio.h>
+#include <stdlib.h> // also null is in <stddef.h>
+#include <stddef.h>
+#include <omp.h>
+#include <string.h>
+
+// ENVIRONMENT
+// OMP_DISPLAY_AFFINITY=TRUE
+// OMP_NUM_THREADS=4
+// OMP_PLACES='{0,1},{2,3},{4,5},{6,7}'
+
+// CHECK: num_threads=1 OMP: pid [0-9]+ tid [0-9]+ thread [0-4] bound to OS proc set \{([0-7])|(0,1)|(undefined)\}
+// CHECK: num_threads=4 Thread id [0-3] reporting in
+// CHECK: num_threads=4 OMP: pid [0-9]+ tid [0-9]+ thread [0-4] bound to OS proc set \{([0-7])|([0246],[1357])|(undefined)\}
+// CHECK: num_threads=1 Default Affinity Format is:
+// CHECK: num_threads=1 Affinity Format set to: host=%20H tid=%0.4n binds_to=%A
+// CHECK: num_threads=4 tid=[0-3] affinity:host=[a-zA-Z0-9_.-]+[ ]+tid=000[0-4][ ]+binds_to=(([0-7])|([0246],[1357])|(undefined))
+
+#define FORMAT_STORE 80
+#define BUFFER_STORE 80
+
+int main(int argc, char** argv) {
+  int i, n, tid, max_req_store = 0;
+  size_t nchars;
+  char default_format[FORMAT_STORE];
+  char my_format[] = "host=%20H tid=%0.4n binds_to=%A";
+  char **buffer;
+
+  // CODE SEGMENT 1 AFFINITY DISPLAY
+  omp_display_affinity(NULL);
+
+  // OMP_DISPLAY_AFFINITY=TRUE,
+  // Affinity reported for 1 parallel region
+  #pragma omp parallel
+  {
+    printf("Thread id %d reporting in.\n", omp_get_thread_num());
+  }
+
+  // Get and Display Default Affinity Format
+  nchars = omp_get_affinity_format(default_format, (size_t)FORMAT_STORE);
+  printf("Default Affinity Format is: %s\n", default_format);
+
+  if (nchars > FORMAT_STORE) {
+    printf("Caution: Reported Format is truncated. Increase\n");
+    printf(" FORMAT_STORE by %d.\n", (int)nchars - FORMAT_STORE);
+  }
+
+  // Set Affinity Format
+  omp_set_affinity_format(my_format);
+  printf("Affinity Format set to: %s\n", my_format);
+
+  // CODE SEGMENT 3 CAPTURE AFFINITY
+  // Set up buffer for affinity of n threads
+  n = omp_get_max_threads();
+  buffer = (char **)malloc(sizeof(char *) * n);
+  for (i = 0; i < n; i++) {
+    buffer[i] = (char *)malloc(sizeof(char) * BUFFER_STORE);
+  }
+
+  // Capture Affinity using Affinity Format set above.
+  // Use critical reduction to check size of buffer areas
+  #pragma omp parallel private(tid, nchars)
+  {
+    tid = omp_get_thread_num();
+    nchars = omp_capture_affinity(buffer[tid], (size_t)BUFFER_STORE, NULL);
+    #pragma omp critical
+    {
+      if (nchars > max_req_store)
+        max_req_store = nchars;
+    }
+  }
+
+  for (i = 0; i < n; i++) {
+    printf("tid=%d affinity:%s:\n", i, buffer[i]);
+  }
+  // for 4 threads with OMP_PLACES='{0,1},{2,3},{4,5},{6,7}'
+  // host=%20H tid=%0.4n binds_to=%A
+  // host=<hostname> tid=0000 binds_to=0,1
+  // host=<hostname> tid=0001 binds_to=2,3
+  // host=<hostname> tid=0002 binds_to=4,5
+  // host=<hostname> tid=0003 binds_to=6,7
+
+  if (max_req_store > BUFFER_STORE) {
+    printf("Caution: Affinity string truncated. Increase\n");
+    printf(" BUFFER_STORE by %d\n", max_req_store - BUFFER_STORE);
+  }
+  return 0;
+}

Added: openmp/trunk/runtime/test/affinity/format/affinity_values.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/affinity_values.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/affinity_values.c (added)
+++ openmp/trunk/runtime/test/affinity/format/affinity_values.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,123 @@
+// 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>
+#include "helper.h"
+#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;
+}

Added: openmp/trunk/runtime/test/affinity/format/api.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/api.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/api.c (added)
+++ openmp/trunk/runtime/test/affinity/format/api.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,56 @@
+// RUN: %libomp-compile-and-run
+// RUN: %libomp-run | python %S/check.py -c 'CHECK' %s
+
+#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 BUFFER_SIZE 1024
+
+int main(int argc, char** argv) {
+  char buf[BUFFER_SIZE];
+  size_t needed;
+
+  omp_set_affinity_format("0123456789");
+
+  needed = omp_get_affinity_format(buf, BUFFER_SIZE);
+  check(streqls(buf, "0123456789"));
+  check(needed == 10)
+
+  // Check that it is truncated properly
+  omp_get_affinity_format(buf, 5);
+  check(streqls(buf, "0123"));
+
+  #pragma omp parallel
+  {
+    char my_buf[512];
+    size_t needed = omp_capture_affinity(my_buf, 512, NULL);
+    check(streqls(my_buf, "0123456789"));
+    check(needed == 10);
+    // Check that it is truncated properly
+    omp_capture_affinity(my_buf, 5, NULL);
+    check(streqls(my_buf, "0123"));
+  }
+
+  #pragma omp parallel num_threads(4)
+  {
+    omp_display_affinity(NULL);
+  }
+
+  return 0;
+}
+
+// CHECK: num_threads=4 0123456789

Added: openmp/trunk/runtime/test/affinity/format/api2.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/api2.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/api2.c (added)
+++ openmp/trunk/runtime/test/affinity/format/api2.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,84 @@
+// RUN: %libomp-compile-and-run
+// RUN: %libomp-run | python %S/check.py -c 'CHECK' %s
+
+#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);                                                                   \
+  }
+
+#if defined(_WIN32)
+#define snprintf _snprintf
+#endif
+
+#define BUFFER_SIZE 1024
+
+int main(int argc, char** argv) {
+  char buf[BUFFER_SIZE];
+  size_t needed, length;
+  const char* format = "tl:%L tn:%n nt:%N an:%a";
+  const char* second_format = "nesting_level:%{nesting_level} thread_num:%{thread_num} num_threads:%{num_threads} ancestor_tnum:%{ancestor_tnum}";
+
+  length = strlen(format);
+  omp_set_affinity_format(format);
+
+  needed = omp_get_affinity_format(buf, BUFFER_SIZE);
+  check(streqls(buf, format));
+  check(needed == length)
+
+  // Check that it is truncated properly
+  omp_get_affinity_format(buf, 5);
+  check(streqls(buf, "tl:%"));
+
+  #pragma omp parallel
+  {
+    char my_buf[512];
+    char supposed[512];
+    int tl, tn, nt, an;
+    size_t needed, needed2;
+    tl = omp_get_level();
+    tn = omp_get_thread_num();
+    nt = omp_get_num_threads();
+    an = omp_get_ancestor_thread_num(omp_get_level()-1);
+    needed = omp_capture_affinity(my_buf, 512, NULL);
+    needed2 = (size_t)snprintf(supposed, 512, "tl:%d tn:%d nt:%d an:%d", tl, tn, nt, an);
+    check(streqls(my_buf, supposed));
+    check(needed == needed2);
+    // Check that it is truncated properly
+    supposed[4] = '\0';
+    omp_capture_affinity(my_buf, 5, NULL);
+    check(streqls(my_buf, supposed));
+
+    needed = omp_capture_affinity(my_buf, 512, second_format);
+    needed2 = (size_t)snprintf(supposed, 512, "nesting_level:%d thread_num:%d num_threads:%d ancestor_tnum:%d", tl, tn, nt, an);
+    check(streqls(my_buf, supposed));
+    check(needed == needed2);
+
+    // Check that it is truncated properly
+    supposed[25] = '\0';
+    omp_capture_affinity(my_buf, 26, second_format);
+    check(streqls(my_buf, supposed));
+  }
+
+  #pragma omp parallel num_threads(4)
+  {
+    omp_display_affinity(NULL);
+    omp_display_affinity(second_format);
+  }
+
+  return 0;
+}
+
+// CHECK: num_threads=4 tl:[0-9]+ tn:[0-9]+ nt:[0-9]+ an:[0-9]+
+// CHECK: num_threads=4 nesting_level:[0-9]+ thread_num:[0-9]+ num_threads:[0-9]+ ancestor_tnum:[0-9]+

Added: openmp/trunk/runtime/test/affinity/format/check.py
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/check.py?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/check.py (added)
+++ openmp/trunk/runtime/test/affinity/format/check.py Mon Dec 17 14:33:21 2018
@@ -0,0 +1,73 @@
+import os
+import sys
+import argparse
+import re
+
+class Checks(object):
+    class CheckError(Exception):
+        pass
+
+    def __init__(self, filename, prefix):
+        self.checks = []
+        self.lines = []
+        self.check_no_output = False
+        self.filename = filename
+        self.prefix = prefix
+    def readStdin(self):
+        self.lines = [l.rstrip('\r\n') for l in sys.stdin.readlines()]
+    def readChecks(self):
+        with open(self.filename) as f:
+            for line in f:
+                match = re.search('{}: NO_OUTPUT'.format(self.prefix), line)
+                if match is not None:
+                    self.check_no_output = True
+                    return
+                match = re.search('{}: num_threads=([0-9]+) (.*)$'.format(self.prefix), line)
+                if match is not None:
+                    num_threads = int(match.group(1))
+                    for i in range(num_threads):
+                        self.checks.append(match.group(2))
+                    continue
+    def check(self):
+        # If no checks at all, then nothing to do
+        if len(self.checks) == 0 and not self.check_no_output:
+            print('Nothing to check for')
+            return
+        # Check if we are expecting no output
+        if self.check_no_output:
+            if len(self.lines) == 0:
+                return
+            else:
+                raise Checks.CheckError('{}: Output was found when expecting none.'.format(self.prefix))
+        # Run through each check line and see if it exists in the output
+        # If it does, then delete the line from output and look for the
+        # next check line.
+        # If you don't find the line then raise Checks.CheckError
+        # If there are extra lines of output then raise Checks.CheckError
+        for c in self.checks:
+            found = False
+            index = -1
+            for idx, line in enumerate(self.lines):
+                if re.search(c, line) is not None:
+                    found = True
+                    index = idx
+                    break
+            if not found:
+                raise Checks.CheckError('{}: Did not find: {}'.format(self.prefix, c))
+            else:
+                del self.lines[index]
+        if len(self.lines) != 0:
+            raise Checks.CheckError('{}: Extra output: {}'.format(self.prefix, self.lines))
+
+# Setup argument parsing
+parser = argparse.ArgumentParser(description='''This script checks output of
+    a program against "CHECK" lines in filename''')
+parser.add_argument('filename', default=None, help='filename to check against')
+parser.add_argument('-c', '--check-prefix', dest='prefix',
+                    default='CHECK', help='check prefix token default: %(default)s')
+command_args = parser.parse_args()
+# Do the checking
+checks = Checks(command_args.filename, command_args.prefix)
+checks.readStdin()
+checks.readChecks()
+checks.check()

Added: openmp/trunk/runtime/test/affinity/format/fields_modifiers.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/fields_modifiers.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/fields_modifiers.c (added)
+++ openmp/trunk/runtime/test/affinity/format/fields_modifiers.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,117 @@
+// RUN: %libomp-compile-and-run
+
+#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 BUFFER_SIZE 1024
+
+char buf[BUFFER_SIZE];
+#pragma omp threadprivate(buf)
+
+char* get_string(size_t check_needed) {
+  size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL);
+  //printf("buf = %s\n", buf);
+  check(needed < BUFFER_SIZE);
+  if (check_needed != 0) {
+    check(needed == check_needed);
+  }
+  return buf;
+}
+
+void check_thread_num_padded_rjustified() {
+  int i;
+  const char* formats[2] = {"%0.8{thread_num}", "%0.8n"};
+  for (i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) {
+    omp_set_affinity_format(formats[i]);
+    #pragma omp parallel num_threads(8)
+    {
+      int j;
+      int tid = omp_get_thread_num();
+      char ctid = '0' + (char)tid;
+      char* s = get_string(8);
+      for (j = 0; j < 7; ++j) {
+        check(s[j] == '0');
+      }
+      check(s[j] == ctid);
+    }
+  }
+}
+
+void check_thread_num_rjustified() {
+  int i;
+  const char* formats[2] = {"%.12{thread_num}", "%.12n"};
+  for (i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) {
+    omp_set_affinity_format(formats[i]);
+    #pragma omp parallel num_threads(8)
+    {
+      int j;
+      int tid = omp_get_thread_num();
+      char ctid = '0' + (char)tid;
+      char* s = get_string(12);
+      for (j = 0; j < 11; ++j) {
+        check(s[j] == ' ');
+      }
+      check(s[j] == ctid);
+    }
+  }
+}
+
+void check_thread_num_ljustified() {
+  int i;
+  const char* formats[2] = {"%5{thread_num}", "%5n"};
+  for (i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) {
+    omp_set_affinity_format(formats[i]);
+    #pragma omp parallel num_threads(8)
+    {
+      int j;
+      int tid = omp_get_thread_num();
+      char ctid = '0' + (char)tid;
+      char* s = get_string(5);
+      check(s[0] == ctid);
+      for (j = 1; j < 5; ++j) {
+        check(s[j] == ' ');
+      }
+    }
+  }
+}
+
+void check_thread_num_padded_ljustified() {
+  int i;
+  const char* formats[2] = {"%018{thread_num}", "%018n"};
+  for (i = 0; i < sizeof(formats)/sizeof(formats[0]); ++i) {
+    omp_set_affinity_format(formats[i]);
+    #pragma omp parallel num_threads(8)
+    {
+      int j;
+      int tid = omp_get_thread_num();
+      char ctid = '0' + (char)tid;
+      char* s = get_string(18);
+      check(s[0] == ctid);
+      for (j = 1; j < 18; ++j) {
+        check(s[j] == ' ');
+      }
+    }
+  }
+}
+
+int main(int argc, char** argv) {
+  check_thread_num_ljustified();
+  check_thread_num_rjustified();
+  check_thread_num_padded_ljustified();
+  check_thread_num_padded_rjustified();
+  return 0;
+}

Added: openmp/trunk/runtime/test/affinity/format/fields_values.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/fields_values.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/fields_values.c (added)
+++ openmp/trunk/runtime/test/affinity/format/fields_values.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,152 @@
+// RUN: %libomp-compile-and-run
+
+#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);                                                                   \
+  }
+
+#if defined(_WIN32)
+#include <windows.h>
+#define getpid _getpid
+typedef int pid_t;
+#define gettid GetCurrentThreadId
+#define my_gethostname(buf, sz) GetComputerNameA(buf, &(sz))
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#define my_gethostname(buf, sz) gethostname(buf, sz)
+#endif
+
+#define BUFFER_SIZE 256
+
+int get_integer() {
+  int n, retval;
+  char buf[BUFFER_SIZE];
+  size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL);
+  check(needed < BUFFER_SIZE);
+  n = sscanf(buf, "%d", &retval);
+  check(n == 1);
+  return retval;
+}
+
+char* get_string() {
+  int n, retval;
+  char buf[BUFFER_SIZE];
+  size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL);
+  check(needed < BUFFER_SIZE);
+  return strdup(buf);
+}
+
+void check_integer(const char* formats[2], int(*func)()) {
+  int i;
+  for (i = 0; i < 2; ++i) {
+    omp_set_affinity_format(formats[i]);
+    #pragma omp parallel num_threads(8)
+    {
+      check(get_integer() == func());
+      #pragma omp parallel num_threads(3)
+      {
+        check(get_integer() == func());
+      }
+      check(get_integer() == func());
+    }
+  }
+}
+
+void check_nesting_level() {
+  // Check %{nesting_level} and %L
+  const char* formats[2] = {"%{nesting_level}", "%L"};
+  check_integer(formats, omp_get_level);
+}
+
+void check_thread_num() {
+  // Check %{thread_num} and %n
+  const char* formats[2] = {"%{thread_num}", "%n"};
+  check_integer(formats, omp_get_thread_num);
+}
+
+void check_num_threads() {
+  // Check %{num_threads} and %N
+  const char* formats[2] = {"%{num_threads}", "%N"};
+  check_integer(formats, omp_get_num_threads);
+}
+
+int ancestor_helper() {
+  return omp_get_ancestor_thread_num(omp_get_level() - 1);
+}
+void check_ancestor_tnum() {
+  // Check %{ancestor_tnum} and %a
+  const char* formats[2] = {"%{ancestor_tnum}", "%a"};
+  check_integer(formats, ancestor_helper);
+}
+
+int my_get_pid() { return (int)getpid(); }
+void check_process_id() {
+  // Check %{process_id} and %P
+  const char* formats[2] = {"%{process_id}", "%P"};
+  check_integer(formats, my_get_pid);
+}
+
+/*
+int my_get_tid() { return (int)gettid(); }
+void check_native_thread_id() {
+  // Check %{native_thread_id} and %i
+  const char* formats[2] = {"%{native_thread_id}", "%i"};
+  check_integer(formats, my_get_tid);
+}
+*/
+
+void check_host() {
+  int i;
+  int buffer_size = 256;
+  const char* formats[2] = {"%{host}", "%H"};
+  char hostname[256];
+  my_gethostname(hostname, buffer_size);
+  for (i = 0; i < 2; ++i) {
+    omp_set_affinity_format(formats[i]);
+    #pragma omp parallel num_threads(8)
+    {
+      char* host = get_string();
+      check(streqls(host, hostname));
+      free(host);
+    }
+  }
+}
+
+void check_undefined() {
+  int i;
+  const char* formats[2] = {"%{foobar}", "%X"};
+  for (i = 0; i < 2; ++i) {
+    omp_set_affinity_format(formats[i]);
+    #pragma omp parallel num_threads(8)
+    {
+      char* undef = get_string();
+      check(streqls(undef, "undefined"));
+      free(undef);
+    }
+  }
+}
+
+int main(int argc, char** argv) {
+  omp_set_nested(1);
+  check_nesting_level();
+  check_num_threads();
+  check_ancestor_tnum();
+  check_process_id();
+  //check_native_thread_id();
+  check_host();
+  check_undefined();
+  return 0;
+}

Added: openmp/trunk/runtime/test/affinity/format/increase.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/increase.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/increase.c (added)
+++ openmp/trunk/runtime/test/affinity/format/increase.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,36 @@
+// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true %libomp-run | python %S/check.py -c 'CHECK' %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+int main(int argc, char** argv) {
+  omp_set_affinity_format("TESTER: tl:%L tn:%n nt:%N");
+  // should print all for first parallel
+  omp_set_num_threads(4);
+  #pragma omp parallel
+  { }
+  // should print all because of new threads
+  omp_set_num_threads(8);
+  #pragma omp parallel
+  { }
+  // should not print anything here
+  omp_set_num_threads(6);
+  #pragma omp parallel
+  { }
+  // should print all because of new thread
+  omp_set_num_threads(9);
+  #pragma omp parallel
+  { }
+  // should not print anything here
+  omp_set_num_threads(2);
+  #pragma omp parallel
+  { }
+  return 0;
+}
+
+// CHECK: num_threads=4 TESTER: tl:1 tn:[0-3] nt:4
+// CHECK: num_threads=8 TESTER: tl:1 tn:[0-7] nt:8
+// CHECK: num_threads=6 TESTER: tl:1 tn:[0-5] nt:6
+// CHECK: num_threads=9 TESTER: tl:1 tn:[0-8] nt:9
+// CHECK: num_threads=2 TESTER: tl:1 tn:[01] nt:2

Added: openmp/trunk/runtime/test/affinity/format/nested.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/nested.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/nested.c (added)
+++ openmp/trunk/runtime/test/affinity/format/nested.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,23 @@
+// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true OMP_PLACES=threads OMP_PROC_BIND=spread,close %libomp-run | python %S/check.py -c 'CHECK' %s
+// REQUIRES: affinity
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+int main(int argc, char** argv) {
+  omp_set_affinity_format("TESTER: tl:%L at:%a tn:%n nt:%N");
+  omp_set_nested(1);
+  #pragma omp parallel num_threads(4)
+  {
+    #pragma omp parallel num_threads(3)
+    { }
+  }
+  return 0;
+}
+
+// CHECK: num_threads=4 TESTER: tl:1 at:0 tn:[0-3] nt:4
+// CHECK: num_threads=3 TESTER: tl:2 at:[0-3] tn:[0-2] nt:3
+// CHECK: num_threads=3 TESTER: tl:2 at:[0-3] tn:[0-2] nt:3
+// CHECK: num_threads=3 TESTER: tl:2 at:[0-3] tn:[0-2] nt:3
+// CHECK: num_threads=3 TESTER: tl:2 at:[0-3] tn:[0-2] nt:3

Added: openmp/trunk/runtime/test/affinity/format/nested2.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/nested2.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/nested2.c (added)
+++ openmp/trunk/runtime/test/affinity/format/nested2.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,29 @@
+// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true OMP_PLACES=threads OMP_PROC_BIND=spread,close KMP_HOT_TEAMS_MAX_LEVEL=2 %libomp-run | python %S/check.py -c 'CHECK' %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+// Currently, KMP_HOT_TEAMS_MAX_LEVEL has to be equal to the
+// nest depth for intuitive behavior
+int main(int argc, char** argv) {
+  omp_set_affinity_format("TESTER: tl:%L tn:%n nt:%N");
+  omp_set_nested(1);
+  #pragma omp parallel num_threads(4)
+  {
+    #pragma omp parallel num_threads(3)
+    { }
+    #pragma omp parallel num_threads(3)
+    { }
+  }
+  #pragma omp parallel num_threads(4)
+  { }
+  return 0;
+}
+
+// CHECK: num_threads=4 TESTER: tl:1 tn:[0-3] nt:4
+// CHECK: num_threads=3 TESTER: tl:2 tn:[0-2] nt:3
+// CHECK: num_threads=3 TESTER: tl:2 tn:[0-2] nt:3
+// CHECK: num_threads=3 TESTER: tl:2 tn:[0-2] nt:3
+// CHECK: num_threads=3 TESTER: tl:2 tn:[0-2] nt:3
+// CHECK: num_threads=4 TESTER: tl:1 tn:[0-3] nt:4

Added: openmp/trunk/runtime/test/affinity/format/nested_mixed.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/nested_mixed.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/nested_mixed.c (added)
+++ openmp/trunk/runtime/test/affinity/format/nested_mixed.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,46 @@
+// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true %libomp-run | python %S/check.py -c 'CHECK' %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+int main(int argc, char** argv) {
+  omp_set_affinity_format("TESTER: tl:%L at:%a tn:%n nt:%N");
+  omp_set_nested(1);
+  #pragma omp parallel num_threads(1)
+  {
+    #pragma omp parallel num_threads(2)
+    { }
+    #pragma omp parallel num_threads(2)
+    {
+      #pragma omp parallel num_threads(1)
+      {
+        #pragma omp parallel num_threads(2)
+        { }
+      }
+    }
+    #pragma omp parallel num_threads(1)
+    { }
+  }
+  #pragma omp parallel num_threads(2)
+  { }
+  #pragma omp parallel num_threads(1)
+  { }
+  return 0;
+}
+
+// CHECK: num_threads=1 TESTER: tl:1 at:0 tn:0 nt:1
+
+// CHECK: num_threads=2 TESTER: tl:2 at:[0-9] tn:[01] nt:2
+
+// CHECK: num_threads=1 TESTER: tl:3 at:[0-9] tn:0 nt:1
+// CHECK: num_threads=1 TESTER: tl:3 at:[0-9] tn:0 nt:1
+
+// CHECK: num_threads=2 TESTER: tl:4 at:[0-9] tn:[01] nt:2
+// CHECK: num_threads=2 TESTER: tl:4 at:[0-9] tn:[01] nt:2
+
+// CHECK: num_threads=1 TESTER: tl:2 at:[0-9] tn:0 nt:1
+
+// CHECK: num_threads=2 TESTER: tl:1 at:[0-9] tn:[01] nt:2
+
+// CHECK: num_threads=1 TESTER: tl:1 at:[0-9] tn:0 nt:1

Added: openmp/trunk/runtime/test/affinity/format/nested_serial.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/nested_serial.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/nested_serial.c (added)
+++ openmp/trunk/runtime/test/affinity/format/nested_serial.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,35 @@
+// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true %libomp-run | python %S/check.py -c 'CHECK' %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+int main(int argc, char** argv) {
+  omp_set_affinity_format("TESTER: tl:%L at:%a tn:%n nt:%N");
+  omp_set_nested(1);
+  #pragma omp parallel num_threads(1)
+  {
+    #pragma omp parallel num_threads(1)
+    { }
+    #pragma omp parallel num_threads(1)
+    { }
+    #pragma omp parallel num_threads(1)
+    {
+      #pragma omp parallel num_threads(1)
+      { }
+    }
+    #pragma omp parallel num_threads(1)
+    { }
+  }
+  #pragma omp parallel num_threads(1)
+  { }
+  #pragma omp parallel num_threads(1)
+  { }
+  return 0;
+}
+
+// CHECK: num_threads=1 TESTER: tl:1 at:0 tn:0 nt:1
+// CHECK: num_threads=1 TESTER: tl:2 at:0 tn:0 nt:1
+// CHECK: num_threads=1 TESTER: tl:3 at:0 tn:0 nt:1
+// CHECK: num_threads=1 TESTER: tl:2 at:0 tn:0 nt:1
+// CHECK: num_threads=1 TESTER: tl:1 at:0 tn:0 nt:1

Added: openmp/trunk/runtime/test/affinity/format/proc_bind.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/proc_bind.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/proc_bind.c (added)
+++ openmp/trunk/runtime/test/affinity/format/proc_bind.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,31 @@
+// RUN: %libomp-compile && env OMP_DISPLAY_AFFINITY=true OMP_PLACES='{0},{0,1},{0},{0,1},{0},{0,1},{0},{0,1},{0},{0,1},{0}' %libomp-run | python %S/check.py -c 'CHECK' %s
+// REQUIRES: affinity
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+int main(int argc, char** argv) {
+  omp_set_affinity_format("TESTER: tl:%L tn:%n nt:%N aff:{%A}");
+  omp_set_num_threads(8);
+  // Initial parallel
+  #pragma omp parallel proc_bind(spread)
+  { }
+  #pragma omp parallel proc_bind(spread)
+  { }
+  // Affinity changes here
+  #pragma omp parallel proc_bind(close)
+  { }
+  #pragma omp parallel proc_bind(close)
+  { }
+  // Affinity changes here
+  #pragma omp parallel proc_bind(master)
+  { }
+  #pragma omp parallel proc_bind(master)
+  { }
+  return 0;
+}
+
+// CHECK: num_threads=8 TESTER: tl:1 tn:[0-7] nt:8 aff:
+// CHECK: num_threads=8 TESTER: tl:1 tn:[0-7] nt:8 aff:
+// CHECK: num_threads=8 TESTER: tl:1 tn:[0-7] nt:8 aff:

Added: openmp/trunk/runtime/test/affinity/format/simple.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/simple.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/simple.c (added)
+++ openmp/trunk/runtime/test/affinity/format/simple.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,27 @@
+// RUN: %libomp-compile
+// RUN: env OMP_DISPLAY_AFFINITY=false %libomp-run | python %S/check.py -c 'NOTHING' %s
+// RUN: env OMP_DISPLAY_AFFINITY=true OMP_NUM_THREADS=1 %libomp-run | python %S/check.py -c 'CHECK' %s
+// RUN: env OMP_DISPLAY_AFFINITY=true OMP_NUM_THREADS=2 %libomp-run | python %S/check.py -c 'CHECK-2' %s
+// RUN: env OMP_DISPLAY_AFFINITY=true OMP_NUM_THREADS=3 %libomp-run | python %S/check.py -c 'CHECK-3' %s
+// RUN: env OMP_DISPLAY_AFFINITY=true OMP_NUM_THREADS=4 %libomp-run | python %S/check.py -c 'CHECK-4' %s
+// RUN: env OMP_DISPLAY_AFFINITY=true OMP_NUM_THREADS=8 %libomp-run | python %S/check.py -c 'CHECK-8' %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+int main(int argc, char** argv) {
+  omp_set_affinity_format("TESTER: tl:%L tn:%n nt:%N");
+  #pragma omp parallel
+  { }
+  #pragma omp parallel
+  { }
+  return 0;
+}
+
+// NOTHING: NO_OUTPUT
+// CHECK: num_threads=1 TESTER: tl:1 tn:0 nt:1
+// CHECK-2: num_threads=2 TESTER: tl:1 tn:[01] nt:2
+// CHECK-3: num_threads=3 TESTER: tl:1 tn:[0-2] nt:3
+// CHECK-4: num_threads=4 TESTER: tl:1 tn:[0-3] nt:4
+// CHECK-8: num_threads=8 TESTER: tl:1 tn:[0-7] nt:8

Added: openmp/trunk/runtime/test/affinity/format/simple_env.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/affinity/format/simple_env.c?rev=349411&view=auto
==============================================================================
--- openmp/trunk/runtime/test/affinity/format/simple_env.c (added)
+++ openmp/trunk/runtime/test/affinity/format/simple_env.c Mon Dec 17 14:33:21 2018
@@ -0,0 +1,16 @@
+// RUN: %libomp-compile
+// RUN: env OMP_DISPLAY_AFFINITY=true OMP_AFFINITY_FORMAT='TESTER-ENV: tl:%L tn:%n nt:%N' OMP_NUM_THREADS=8 %libomp-run | python %S/check.py -c 'CHECK-8' %s
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+
+int main(int argc, char** argv) {
+  #pragma omp parallel
+  { }
+  #pragma omp parallel
+  { }
+  return 0;
+}
+
+// CHECK-8: num_threads=8 TESTER-ENV: tl:1 tn:[0-7] nt:8




More information about the Openmp-commits mailing list