Skip to content

[offload][ompt] Added lookup function for device callbacks #110007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

kaloyan-ignatov
Copy link
Contributor

  • replaced generic OMPT lookup function being provided by ompt_callback_device_initialize with a device-specific lookup function
  • implemented device-specific lookup function
  • added callback placeholders for not yet implemented device OMPT functions

An open question is how to go about testing that the lookup function returns pointers to the actual placeholders. Is there an existing test where this can be added, or does a separate one need to be made?

@llvmbot llvmbot added openmp:libomp OpenMP host runtime offload labels Sep 25, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2024

@llvm/pr-subscribers-offload

Author: Kaloyan Ignatov (kaloyan-ignatov)

Changes
  • replaced generic OMPT lookup function being provided by ompt_callback_device_initialize with a device-specific lookup function
  • implemented device-specific lookup function
  • added callback placeholders for not yet implemented device OMPT functions

An open question is how to go about testing that the lookup function returns pointers to the actual placeholders. Is there an existing test where this can be added, or does a separate one need to be made?


Full diff: https://github.com/llvm/llvm-project/pull/110007.diff

4 Files Affected:

  • (modified) offload/include/OpenMP/OMPT/Callback.h (+2)
  • (modified) offload/src/OpenMP/OMPT/Callback.cpp (+65-1)
  • (modified) openmp/runtime/src/include/omp-tools.h.var (+17)
  • (modified) openmp/runtime/src/ompt-general.cpp (+2)
diff --git a/offload/include/OpenMP/OMPT/Callback.h b/offload/include/OpenMP/OMPT/Callback.h
index 68cb43745eb1f8..afe54ea2ebb2c7 100644
--- a/offload/include/OpenMP/OMPT/Callback.h
+++ b/offload/include/OpenMP/OMPT/Callback.h
@@ -49,6 +49,8 @@ namespace omp {
 namespace target {
 namespace ompt {
 
+extern ompt_interface_fn_t ompt_device_fn_lookup(const char *s);
+
 #define declareOmptCallback(Name, Type, Code) extern Name##_t Name##_fn;
 FOREACH_OMPT_NOEMI_EVENT(declareOmptCallback)
 FOREACH_OMPT_EMI_EVENT(declareOmptCallback)
diff --git a/offload/src/OpenMP/OMPT/Callback.cpp b/offload/src/OpenMP/OMPT/Callback.cpp
index ab0942ed4fd3f7..4da140f85025b3 100644
--- a/offload/src/OpenMP/OMPT/Callback.cpp
+++ b/offload/src/OpenMP/OMPT/Callback.cpp
@@ -27,6 +27,8 @@
 #undef DEBUG_PREFIX
 #define DEBUG_PREFIX "OMPT"
 
+using namespace llvm::omp::target::ompt;
+
 // Define OMPT callback functions (bound to actual callbacks later on)
 #define defineOmptCallback(Name, Type, Code)                                   \
   Name##_t llvm::omp::target::ompt::Name##_fn = nullptr;
@@ -34,7 +36,69 @@ FOREACH_OMPT_NOEMI_EVENT(defineOmptCallback)
 FOREACH_OMPT_EMI_EVENT(defineOmptCallback)
 #undef defineOmptCallback
 
-using namespace llvm::omp::target::ompt;
+int ompt_get_device_num_procs(ompt_device_t *device) { return 0; }
+
+ompt_device_time_t ompt_get_device_time(ompt_device_t *device) { return 0; }
+
+double ompt_translate_time(ompt_device_t *device, ompt_device_time_t time) {
+  return 0;
+}
+
+ompt_set_result_t ompt_set_trace_ompt(ompt_device_t *device,
+                                        unsigned int enable,
+                                        unsigned int etype) {
+  return ompt_set_error;
+}
+
+ompt_set_result_t ompt_set_trace_native(ompt_device_t *device, int enable,
+                                          int flags) {
+  return ompt_set_error;
+}
+
+int ompt_start_trace(ompt_device_t *device,
+                       ompt_callback_buffer_request_t request,
+                       ompt_callback_buffer_complete_t complete) {
+  return 0;
+}
+
+int ompt_pause_trace(ompt_device_t *device, int begin_pause) { return 0; }
+
+int ompt_flush_trace(ompt_device_t *device) { return 0; }
+
+int ompt_stop_trace(ompt_device_t *device) { return 0; }
+
+int ompt_advance_buffer_cursor(ompt_device_t *device, ompt_buffer_t *buffer,
+                                 size_t size, ompt_buffer_cursor_t current,
+                                 ompt_buffer_cursor_t *next) {
+  return 0;
+}
+
+ompt_record_t ompt_get_record_type(ompt_buffer_t *buffer,
+                                     ompt_buffer_cursor_t current) {
+  return ompt_record_ompt;
+}
+
+void *ompt_get_record_native(ompt_buffer_t *buffer,
+                               ompt_buffer_cursor_t current,
+                               ompt_id_t *host_op_id) {
+  return NULL;
+}
+
+ompt_record_abstract_t *ompt_get_record_abstract(void *native_record) {
+  return NULL;
+}
+
+ompt_interface_fn_t llvm::omp::target::ompt::ompt_device_fn_lookup(const char *s) {
+#define ompt_interface_fn(fn)                                                  \
+  fn##_t fn##_f = fn;                                                          \
+  if (strcmp(s, #fn) == 0)                                                     \
+    return (ompt_interface_fn_t)fn##_f;
+
+  FOREACH_OMPT_DEVICE_INQUIRY_FN(ompt_interface_fn)
+#undef ompt_interface_fn
+  return NULL;
+}
+
 
 /// Forward declaration
 class LibomptargetRtlFinalizer;
diff --git a/openmp/runtime/src/include/omp-tools.h.var b/openmp/runtime/src/include/omp-tools.h.var
index 471f46a9073ee7..92017c69ea244b 100644
--- a/openmp/runtime/src/include/omp-tools.h.var
+++ b/openmp/runtime/src/include/omp-tools.h.var
@@ -60,6 +60,23 @@
     macro(ompt_get_target_info)             \
     macro(ompt_get_num_devices)
 
+#define FOREACH_OMPT_DEVICE_INQUIRY_FN(macro) \
+    macro (ompt_get_device_num_procs)         \
+    macro (ompt_get_device_time)             \
+    macro (ompt_translate_time)             \
+    macro (ompt_set_trace_ompt)             \
+    macro (ompt_set_trace_native)             \
+    /* macro (ompt_get_buffer_limits) */          \
+    macro (ompt_start_trace)             \
+    macro (ompt_pause_trace)             \
+    macro (ompt_flush_trace)             \
+    macro (ompt_stop_trace)             \
+    macro (ompt_advance_buffer_cursor)             \
+    macro (ompt_get_record_type)             \
+    /* macro (ompt_get_record_ompt) */      \
+    macro (ompt_get_record_native)       \
+    macro (ompt_get_record_abstract)
+
 #define FOREACH_OMPT_STATE(macro)                                                                \
                                                                                                 \
     /* first available state */                                                                 \
diff --git a/openmp/runtime/src/ompt-general.cpp b/openmp/runtime/src/ompt-general.cpp
index 923eea2a563a91..fa8d8019d5ea13 100644
--- a/openmp/runtime/src/ompt-general.cpp
+++ b/openmp/runtime/src/ompt-general.cpp
@@ -121,6 +121,8 @@ static ompt_start_tool_result_t *libomptarget_ompt_result = NULL;
 
 static ompt_interface_fn_t ompt_fn_lookup(const char *s);
 
+static ompt_interface_fn_t ompt_device_fn_lookup(const char *s);
+
 OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(void);
 
 /*****************************************************************************

Copy link

github-actions bot commented Sep 25, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@@ -60,6 +60,23 @@
macro(ompt_get_target_info) \
macro(ompt_get_num_devices)

#define FOREACH_OMPT_DEVICE_INQUIRY_FN(macro) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, clang-format does not format this file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can call it manually, but it might change a lot of unrelated stuff.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can push a NFC first

// Define OMPT callback functions (bound to actual callbacks later on)
#define defineOmptCallback(Name, Type, Code) \
Name##_t llvm::omp::target::ompt::Name##_fn = nullptr;
FOREACH_OMPT_NOEMI_EVENT(defineOmptCallback)
FOREACH_OMPT_EMI_EVENT(defineOmptCallback)
#undef defineOmptCallback

using namespace llvm::omp::target::ompt;
int ompt_get_device_num_procs(ompt_device_t *device) { return 0; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to clang-format this seems to be fine

@jprotze
Copy link
Collaborator

jprotze commented Sep 25, 2024

@mhalk this one of the issues we talked about last week. I you have a better solution downstream, we can withdraw this PR

…olders for not yet implemented device callbacks
using namespace llvm::omp::target::ompt;
int ompt_get_device_num_procs(ompt_device_t *device) { return 0; }

ompt_device_time_t ompt_get_device_time(ompt_device_t *device) { return 0; }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use ompt_time_none instead? See 19.4.4.6 in the OpenMP 5.2 spec.


ompt_set_result_t ompt_set_trace_ompt(ompt_device_t *device,
unsigned int enable, unsigned int etype) {
return ompt_set_error;
Copy link

@Thyre Thyre Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not choose ompt_set_error, as tools could think they did something wrong (e.g. tried to use target_emi and target at the same time, which is not allowed).
We should return ompt_set_never instead.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ompt_set_error could still be used when trying to call this function outside of the ompt_callback_device_initialize callback, see the OpenMP 5.2 spec.

If the ompt_set_trace_native or the ompt_set_trace_ompt runtime entry point is called outside a device initializer, registration of supported callbacks may fail with a return code of ompt_set_error.


ompt_set_result_t ompt_set_trace_native(ompt_device_t *device, int enable,
int flags) {
return ompt_set_error;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as ompt_set_trace_ompt

@Thyre
Copy link

Thyre commented Sep 26, 2024

Aside from my comments, this looks mostly fine. It basically resembles what we were seeing with oneAPI until they removed the lookup stuff in 2024.1.0. However, this approach correctly returns that trying to register anything device tracing related will not work.

I'm not sure if it makes sense to implement the lookup functions like ompt_get_device_time if they return not-implemented values, but it's a starting point. I would rather not implement them and return NULL if a tool tries to get the function pointer.

@mhalk
Copy link
Contributor

mhalk commented Sep 26, 2024

@mhalk this one of the issues we talked about last week. I you have a better solution downstream, we can withdraw this PR

@jprotze Thanks for the ping!

Yes, we have another solution (esp. w.r.t. device tracing) downstream, which needs a bit of prepartation before actual upstreaming.
Currently, this PR would conflict with our downstream implementation.

We'd like to discuss further steps offline as this is beyond this PR and we'll reach out to you by mail.
For our understanding it would e.g. be helpful to understand if this is the first PR in a series and generally what you'd want to achieve.

I think this might be a good opportunity to bring upstream device-tracing forward.
(Also, I'll add some links our downstream implementation.)

@@ -60,6 +60,23 @@
macro(ompt_get_target_info) \
macro(ompt_get_num_devices)

#define FOREACH_OMPT_DEVICE_INQUIRY_FN(macro) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downstream examples (e.g. here I like this location way better):
https://github.com/ROCm/llvm-project/blob/amd-staging/offload/include/OmptCommonDefs.h#L26-L46

return 0;
}

ompt_set_result_t ompt_set_trace_ompt(ompt_device_t *device,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -767,7 +767,7 @@ Error GenericDeviceTy::init(GenericPluginTy &Plugin) {
performOmptCallback(device_initialize, Plugin.getUserId(DeviceId),
/*type=*/getComputeUnitKind().c_str(),
/*device=*/reinterpret_cast<ompt_device_t *>(this),
/*lookup=*/ompt::lookupCallbackByName,
/*lookup=*/ompt::ompt_device_fn_lookup,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
offload openmp:libomp OpenMP host runtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants