diff options
author | Jonathan Peyton <jonathan.l.peyton@intel.com> | 2018-12-13 23:14:24 +0000 |
---|---|---|
committer | Jonathan Peyton <jonathan.l.peyton@intel.com> | 2018-12-13 23:14:24 +0000 |
commit | 09185848651b1cfab16634c40b3151ec5dad9567 (patch) | |
tree | bbc9ce7321bfe7cc7955973ab5f0bb2df93a794c /runtime/src/kmp_affinity.cpp | |
parent | 12258aa8d931d81cb7673994caa96bcc457256f8 (diff) |
[OpenMP] Implement OpenMP 5.0 affinity format functionality
This patch adds the affinity format functionality introduced in OpenMP 5.0.
This patch adds: Two new environment variables:
OMP_DISPLAY_AFFINITY=TRUE|FALSE
OMP_AFFINITY_FORMAT=<string>
and Four new API:
1) omp_set_affinity_format()
2) omp_get_affinity_format()
3) omp_display_affinity()
4) omp_capture_affinity()
The affinity format functionality has two ICV's associated with it:
affinity-display-var (bool) and affinity-format-var (string).
The affinity-display-var enables/disables the functionality through the
envirable OMP_DISPLAY_AFFINITY. The affinity-format-var is a formatted
string with the special field types beginning with a '%' character
similar to printf
For example, the affinity-format-var could be:
"OMP: host:%H pid:%P OStid:%i num_threads:%N thread_num:%n affinity:{%A}"
The affinity-format-var is displayed by every thread implicitly at the beginning
of a parallel region when any thread's affinity has changed (including a brand
new thread being spawned), or explicitly using the omp_display_affinity() API.
The omp_capture_affinity() function can capture the affinity-format-var in a
char buffer. And omp_set|get_affinity_format() allow the user to set|get the
affinity-format-var explicitly at runtime. omp_capture_affinity() and
omp_get_affinity_format() both return the number of characters needed to hold
the entire string it tried to make (not including NULL character). If not
enough buffer space is available,
both these functions truncate their output.
Differential Revision: https://reviews.llvm.org/D55148
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@349089 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'runtime/src/kmp_affinity.cpp')
-rw-r--r-- | runtime/src/kmp_affinity.cpp | 140 |
1 files changed, 110 insertions, 30 deletions
diff --git a/runtime/src/kmp_affinity.cpp b/runtime/src/kmp_affinity.cpp index a9a21cf..775862e 100644 --- a/runtime/src/kmp_affinity.cpp +++ b/runtime/src/kmp_affinity.cpp @@ -83,55 +83,135 @@ void KMPAffinity::destroy_api() { } } +#define KMP_ADVANCE_SCAN(scan) \ + while (*scan != '\0') { \ + scan++; \ + } + // Print the affinity mask to the character array in a pretty format. +// The format is a comma separated list of non-negative integers or integer +// ranges: e.g., 1,2,3-5,7,9-15 +// The format can also be the string "{<empty>}" if no bits are set in mask char *__kmp_affinity_print_mask(char *buf, int buf_len, kmp_affin_mask_t *mask) { + int start = 0, finish = 0, previous = 0; + bool first_range; + KMP_ASSERT(buf); KMP_ASSERT(buf_len >= 40); + KMP_ASSERT(mask); char *scan = buf; char *end = buf + buf_len - 1; - // Find first element / check for empty set. - int i; - i = mask->begin(); - if (i == mask->end()) { + // Check for empty set. + if (mask->begin() == mask->end()) { KMP_SNPRINTF(scan, end - scan + 1, "{<empty>}"); - while (*scan != '\0') - scan++; + KMP_ADVANCE_SCAN(scan); KMP_ASSERT(scan <= end); return buf; } - KMP_SNPRINTF(scan, end - scan + 1, "{%d", i); - while (*scan != '\0') - scan++; - i++; - for (; i != mask->end(); i = mask->next(i)) { - if (!KMP_CPU_ISSET(i, mask)) { - continue; + first_range = true; + start = mask->begin(); + while (1) { + // Find next range + // [start, previous] is inclusive range of contiguous bits in mask + for (finish = mask->next(start), previous = start; + finish == previous + 1 && finish != mask->end(); + finish = mask->next(finish)) { + previous = finish; } - // Check for buffer overflow. A string of the form ",<n>" will have at most - // 10 characters, plus we want to leave room to print ",...}" if the set is - // too large to print for a total of 15 characters. We already left room for - // '\0' in setting end. - if (end - scan < 15) { - break; + // The first range does not need a comma printed before it, but the rest + // of the ranges do need a comma beforehand + if (!first_range) { + KMP_SNPRINTF(scan, end - scan + 1, "%s", ","); + KMP_ADVANCE_SCAN(scan); + } else { + first_range = false; } - KMP_SNPRINTF(scan, end - scan + 1, ",%-d", i); - while (*scan != '\0') - scan++; - } - if (i != mask->end()) { - KMP_SNPRINTF(scan, end - scan + 1, ",..."); - while (*scan != '\0') - scan++; + // Range with three or more contiguous bits in the affinity mask + if (previous - start > 1) { + KMP_SNPRINTF(scan, end - scan + 1, "%d-%d", static_cast<int>(start), + static_cast<int>(previous)); + } else { + // Range with one or two contiguous bits in the affinity mask + KMP_SNPRINTF(scan, end - scan + 1, "%d", static_cast<int>(start)); + KMP_ADVANCE_SCAN(scan); + if (previous - start > 0) { + KMP_SNPRINTF(scan, end - scan + 1, ",%d", static_cast<int>(previous)); + } + } + KMP_ADVANCE_SCAN(scan); + // Start over with new start point + start = finish; + if (start == mask->end()) + break; + // Check for overflow + if (end - scan < 2) + break; } - KMP_SNPRINTF(scan, end - scan + 1, "}"); - while (*scan != '\0') - scan++; + + // Check for overflow KMP_ASSERT(scan <= end); return buf; } +#undef KMP_ADVANCE_SCAN + +// Print the affinity mask to the string buffer object in a pretty format +// The format is a comma separated list of non-negative integers or integer +// ranges: e.g., 1,2,3-5,7,9-15 +// The format can also be the string "{<empty>}" if no bits are set in mask +kmp_str_buf_t *__kmp_affinity_str_buf_mask(kmp_str_buf_t *buf, + kmp_affin_mask_t *mask) { + int start = 0, finish = 0, previous = 0; + bool first_range; + KMP_ASSERT(buf); + KMP_ASSERT(mask); + + __kmp_str_buf_clear(buf); + + // Check for empty set. + if (mask->begin() == mask->end()) { + __kmp_str_buf_print(buf, "%s", "{<empty>}"); + return buf; + } + + first_range = true; + start = mask->begin(); + while (1) { + // Find next range + // [start, previous] is inclusive range of contiguous bits in mask + for (finish = mask->next(start), previous = start; + finish == previous + 1 && finish != mask->end(); + finish = mask->next(finish)) { + previous = finish; + } + + // The first range does not need a comma printed before it, but the rest + // of the ranges do need a comma beforehand + if (!first_range) { + __kmp_str_buf_print(buf, "%s", ","); + } else { + first_range = false; + } + // Range with three or more contiguous bits in the affinity mask + if (previous - start > 1) { + __kmp_str_buf_print(buf, "%d-%d", static_cast<int>(start), + static_cast<int>(previous)); + } else { + // Range with one or two contiguous bits in the affinity mask + __kmp_str_buf_print(buf, "%d", static_cast<int>(start)); + if (previous - start > 0) { + __kmp_str_buf_print(buf, ",%d", static_cast<int>(previous)); + } + } + // Start over with new start point + start = finish; + if (start == mask->end()) + break; + } + return buf; +} void __kmp_affinity_entire_machine_mask(kmp_affin_mask_t *mask) { KMP_CPU_ZERO(mask); |