summaryrefslogtreecommitdiffstats
path: root/openmp/runtime/src/kmp_ftn_entry.h
diff options
context:
space:
mode:
Diffstat (limited to 'openmp/runtime/src/kmp_ftn_entry.h')
-rw-r--r--openmp/runtime/src/kmp_ftn_entry.h195
1 files changed, 139 insertions, 56 deletions
diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h
index c9519014ebd..2d349f0398b 100644
--- a/openmp/runtime/src/kmp_ftn_entry.h
+++ b/openmp/runtime/src/kmp_ftn_entry.h
@@ -21,6 +21,12 @@
#include "kmp_i18n.h"
+#if OMP_50_ENABLED
+// For affinity format functions
+#include "kmp_io.h"
+#include "kmp_str.h"
+#endif
+
#if OMPT_SUPPORT
#include "ompt-specific.h"
#endif
@@ -389,6 +395,137 @@ void FTN_STDCALL FTN_FREE(void *ptr, const omp_allocator_t *allocator) {
__kmpc_free(__kmp_entry_gtid(), ptr, allocator);
#endif
}
+
+/* OpenMP 5.0 affinity format support */
+
+#ifndef KMP_STUB
+static void __kmp_fortran_strncpy_truncate(char *buffer, size_t buf_size,
+ char const *csrc, size_t csrc_size) {
+ size_t capped_src_size = csrc_size;
+ if (csrc_size >= buf_size) {
+ capped_src_size = buf_size - 1;
+ }
+ KMP_STRNCPY_S(buffer, buf_size, csrc, capped_src_size);
+ if (csrc_size >= buf_size) {
+ KMP_DEBUG_ASSERT(buffer[buf_size - 1] == '\0');
+ buffer[buf_size - 1] = csrc[buf_size - 1];
+ } else {
+ for (size_t i = csrc_size; i < buf_size; ++i)
+ buffer[i] = ' ';
+ }
+}
+
+// Convert a Fortran string to a C string by adding null byte
+class ConvertedString {
+ char *buf;
+ kmp_info_t *th;
+
+public:
+ ConvertedString(char const *fortran_str, size_t size) {
+ th = __kmp_get_thread();
+ buf = (char *)__kmp_thread_malloc(th, size + 1);
+ KMP_STRNCPY_S(buf, size + 1, fortran_str, size);
+ buf[size] = '\0';
+ }
+ ~ConvertedString() { __kmp_thread_free(th, buf); }
+ const char *get() const { return buf; }
+};
+#endif // KMP_STUB
+
+/*
+ * Set the value of the affinity-format-var ICV on the current device to the
+ * format specified in the argument.
+*/
+void FTN_STDCALL FTN_SET_AFFINITY_FORMAT(char const *format, size_t size) {
+#ifdef KMP_STUB
+ return;
+#else
+ if (!__kmp_init_serial) {
+ __kmp_serial_initialize();
+ }
+ ConvertedString cformat(format, size);
+ // Since the __kmp_affinity_format variable is a C string, do not
+ // use the fortran strncpy function
+ __kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE,
+ cformat.get(), KMP_STRLEN(cformat.get()));
+#endif
+}
+
+/*
+ * Returns the number of characters required to hold the entire affinity format
+ * specification (not including null byte character) and writes the value of the
+ * affinity-format-var ICV on the current device to buffer. If the return value
+ * is larger than size, the affinity format specification is truncated.
+*/
+size_t FTN_STDCALL FTN_GET_AFFINITY_FORMAT(char *buffer, size_t size) {
+#ifdef KMP_STUB
+ return 0;
+#else
+ size_t format_size;
+ if (!__kmp_init_serial) {
+ __kmp_serial_initialize();
+ }
+ format_size = KMP_STRLEN(__kmp_affinity_format);
+ if (buffer && size) {
+ __kmp_fortran_strncpy_truncate(buffer, size, __kmp_affinity_format,
+ format_size);
+ }
+ return format_size;
+#endif
+}
+
+/*
+ * Prints the thread affinity information of the current thread in the format
+ * specified by the format argument. If the format is NULL or a zero-length
+ * string, the value of the affinity-format-var ICV is used.
+*/
+void FTN_STDCALL FTN_DISPLAY_AFFINITY(char const *format, size_t size) {
+#ifdef KMP_STUB
+ return;
+#else
+ int gtid;
+ if (!TCR_4(__kmp_init_middle)) {
+ __kmp_middle_initialize();
+ }
+ gtid = __kmp_get_gtid();
+ ConvertedString cformat(format, size);
+ __kmp_aux_display_affinity(gtid, cformat.get());
+#endif
+}
+
+/*
+ * Returns the number of characters required to hold the entire affinity format
+ * specification (not including null byte) and prints the thread affinity
+ * information of the current thread into the character string buffer with the
+ * size of size in the format specified by the format argument. If the format is
+ * NULL or a zero-length string, the value of the affinity-format-var ICV is
+ * used. The buffer must be allocated prior to calling the routine. If the
+ * return value is larger than size, the affinity format specification is
+ * truncated.
+*/
+size_t FTN_STDCALL FTN_CAPTURE_AFFINITY(char *buffer, char const *format,
+ size_t buf_size, size_t for_size) {
+#if defined(KMP_STUB)
+ return 0;
+#else
+ int gtid;
+ size_t num_required;
+ kmp_str_buf_t capture_buf;
+ if (!TCR_4(__kmp_init_middle)) {
+ __kmp_middle_initialize();
+ }
+ gtid = __kmp_get_gtid();
+ __kmp_str_buf_init(&capture_buf);
+ ConvertedString cformat(format, for_size);
+ num_required = __kmp_aux_capture_affinity(gtid, cformat.get(), &capture_buf);
+ if (buffer && buf_size) {
+ __kmp_fortran_strncpy_truncate(buffer, buf_size, capture_buf.str,
+ capture_buf.used);
+ }
+ __kmp_str_buf_free(&capture_buf);
+ return num_required;
+#endif
+}
#endif /* OMP_50_ENABLED */
int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)(void) {
@@ -778,34 +915,7 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_TEAMS)(void) {
#ifdef KMP_STUB
return 1;
#else
- kmp_info_t *thr = __kmp_entry_thread();
- if (thr->th.th_teams_microtask) {
- kmp_team_t *team = thr->th.th_team;
- int tlevel = thr->th.th_teams_level;
- int ii = team->t.t_level; // the level of the teams construct
- int dd = team->t.t_serialized;
- int level = tlevel + 1;
- KMP_DEBUG_ASSERT(ii >= tlevel);
- while (ii > level) {
- for (dd = team->t.t_serialized; (dd > 0) && (ii > level); dd--, ii--) {
- }
- if (team->t.t_serialized && (!dd)) {
- team = team->t.t_parent;
- continue;
- }
- if (ii > level) {
- team = team->t.t_parent;
- ii--;
- }
- }
- if (dd > 1) {
- return 1; // teams region is serialized ( 1 team of 1 thread ).
- } else {
- return team->t.t_parent->t.t_nproc;
- }
- } else {
- return 1;
- }
+ return __kmp_aux_get_num_teams();
#endif
}
@@ -813,34 +923,7 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_NUM)(void) {
#ifdef KMP_STUB
return 0;
#else
- kmp_info_t *thr = __kmp_entry_thread();
- if (thr->th.th_teams_microtask) {
- kmp_team_t *team = thr->th.th_team;
- int tlevel = thr->th.th_teams_level; // the level of the teams construct
- int ii = team->t.t_level;
- int dd = team->t.t_serialized;
- int level = tlevel + 1;
- KMP_DEBUG_ASSERT(ii >= tlevel);
- while (ii > level) {
- for (dd = team->t.t_serialized; (dd > 0) && (ii > level); dd--, ii--) {
- }
- if (team->t.t_serialized && (!dd)) {
- team = team->t.t_parent;
- continue;
- }
- if (ii > level) {
- team = team->t.t_parent;
- ii--;
- }
- }
- if (dd > 1) {
- return 0; // teams region is serialized ( 1 team of 1 thread ).
- } else {
- return team->t.t_master_tid;
- }
- } else {
- return 0;
- }
+ return __kmp_aux_get_team_num();
#endif
}
OpenPOWER on IntegriCloud