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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
// 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>
#include <process.h>
#define getpid _getpid
#ifndef __MINGW32__
typedef int pid_t;
#endif
#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;
}
|