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
| // 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;
}
|