1 // RUN: %libomp-compile-and-run 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <omp.h> 7 8 #define XSTR(x) #x 9 #define STR(x) XSTR(x) 10 11 #define streqls(s1, s2) (!strcmp(s1, s2)) 12 13 #define check(condition) \ 14 if (!(condition)) { \ 15 fprintf(stderr, "error: %s: %d: " STR(condition) "\n", __FILE__, \ 16 __LINE__); \ 17 exit(1); \ 18 } 19 20 #if defined(_WIN32) 21 #include <windows.h> 22 #define getpid _getpid 23 typedef int pid_t; 24 #define gettid GetCurrentThreadId 25 #define my_gethostname(buf, sz) GetComputerNameA(buf, &(sz)) 26 #else 27 #include <unistd.h> 28 #include <sys/types.h> 29 #define my_gethostname(buf, sz) gethostname(buf, sz) 30 #endif 31 32 #define BUFFER_SIZE 256 33 34 int get_integer() { 35 int n, retval; 36 char buf[BUFFER_SIZE]; 37 size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL); 38 check(needed < BUFFER_SIZE); 39 n = sscanf(buf, "%d", &retval); 40 check(n == 1); 41 return retval; 42 } 43 44 char* get_string() { 45 int n, retval; 46 char buf[BUFFER_SIZE]; 47 size_t needed = omp_capture_affinity(buf, BUFFER_SIZE, NULL); 48 check(needed < BUFFER_SIZE); 49 return strdup(buf); 50 } 51 52 void check_integer(const char* formats[2], int(*func)()) { 53 int i; 54 for (i = 0; i < 2; ++i) { 55 omp_set_affinity_format(formats[i]); 56 #pragma omp parallel num_threads(8) 57 { 58 check(get_integer() == func()); 59 #pragma omp parallel num_threads(3) 60 { 61 check(get_integer() == func()); 62 } 63 check(get_integer() == func()); 64 } 65 } 66 } 67 68 void check_nesting_level() { 69 // Check %{nesting_level} and %L 70 const char* formats[2] = {"%{nesting_level}", "%L"}; 71 check_integer(formats, omp_get_level); 72 } 73 74 void check_thread_num() { 75 // Check %{thread_num} and %n 76 const char* formats[2] = {"%{thread_num}", "%n"}; 77 check_integer(formats, omp_get_thread_num); 78 } 79 80 void check_num_threads() { 81 // Check %{num_threads} and %N 82 const char* formats[2] = {"%{num_threads}", "%N"}; 83 check_integer(formats, omp_get_num_threads); 84 } 85 86 int ancestor_helper() { 87 return omp_get_ancestor_thread_num(omp_get_level() - 1); 88 } 89 void check_ancestor_tnum() { 90 // Check %{ancestor_tnum} and %a 91 const char* formats[2] = {"%{ancestor_tnum}", "%a"}; 92 check_integer(formats, ancestor_helper); 93 } 94 95 int my_get_pid() { return (int)getpid(); } 96 void check_process_id() { 97 // Check %{process_id} and %P 98 const char* formats[2] = {"%{process_id}", "%P"}; 99 check_integer(formats, my_get_pid); 100 } 101 102 /* 103 int my_get_tid() { return (int)gettid(); } 104 void check_native_thread_id() { 105 // Check %{native_thread_id} and %i 106 const char* formats[2] = {"%{native_thread_id}", "%i"}; 107 check_integer(formats, my_get_tid); 108 } 109 */ 110 111 void check_host() { 112 int i; 113 int buffer_size = 256; 114 const char* formats[2] = {"%{host}", "%H"}; 115 char hostname[256]; 116 my_gethostname(hostname, buffer_size); 117 for (i = 0; i < 2; ++i) { 118 omp_set_affinity_format(formats[i]); 119 #pragma omp parallel num_threads(8) 120 { 121 char* host = get_string(); 122 check(streqls(host, hostname)); 123 free(host); 124 } 125 } 126 } 127 128 void check_undefined() { 129 int i; 130 const char* formats[2] = {"%{foobar}", "%X"}; 131 for (i = 0; i < 2; ++i) { 132 omp_set_affinity_format(formats[i]); 133 #pragma omp parallel num_threads(8) 134 { 135 char* undef = get_string(); 136 check(streqls(undef, "undefined")); 137 free(undef); 138 } 139 } 140 } 141 142 int main(int argc, char** argv) { 143 omp_set_nested(1); 144 check_nesting_level(); 145 check_num_threads(); 146 check_ancestor_tnum(); 147 check_process_id(); 148 //check_native_thread_id(); 149 check_host(); 150 check_undefined(); 151 return 0; 152 } 153