// RUN: %libomp-compile-and-run #include #include #include #include #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 #define getpid _getpid typedef int pid_t; #define gettid GetCurrentThreadId #define my_gethostname(buf, sz) GetComputerNameA(buf, &(sz)) #else #include #include #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; }