Refactor API reference docs (#1125)

* Refactor API reference docs

* refactor API ref docs

* corrections

* consistent naming

* updates

* Update CHANGELOG.md

* improving SEO

* improving SEO

* Update using-rocprofv3.rst

* Update counter_collection_services.md

* Update using-rocprofv3.rst

* Fixing doc build errors

* changelogs and some formatting issues

---------

Co-authored-by: Gopesh Bhardwaj <gopesh.bhardwaj@amd.com>
This commit is contained in:
srawat
2024-10-30 19:39:08 +05:30
committed by GitHub
szülő 762ca819cf
commit 4204042ac6
12 fájl változott, egészen pontosan 412 új sor hozzáadva és 354 régi sor törölve
@@ -1,15 +1,19 @@
# Callback tracing services
---
myst:
html_meta:
"description": "ROCprofiler-SDK is a tooling infrastructure for profiling general-purpose GPU compute applications running on the ROCm software."
"keywords": "ROCprofiler-SDK API reference, ROCprofiler-SDK callback services, Callback services API"
---
## Overview
# ROCprofiler-SDK callback tracing services
Callback tracing services provide immediate callbacks to a tool on the current CPU thread when a given event occurs.
For example, when tracing an API function, e.g. `hipSetDevice`, callback tracing invokes a user-specified callback
before and after the traced function executes on the thread which is invoking the API function.
Callback tracing services provide immediate callbacks to a tool on the current CPU thread on the occurrence of an event.
For example, when tracing an API function such as `hipSetDevice`, callback tracing invokes a user-specified callback
before and after the traced function executes on the thread invoking the API function.
## Subscribing to Callback Tracing Services
## Subscribing to callback tracing services
During tool initialization, tools configure callback tracing via the `rocprofiler_configure_callback_tracing_service`
function:
During tool initialization, tools configure callback tracing using:
```cpp
rocprofiler_status_t
@@ -21,18 +25,20 @@ rocprofiler_configure_callback_tracing_service(rocprofiler_context_id_t
void* callback_args);
```
The `kind` parameter is a high-level specifier of which service to trace (also known as a "domain").
Domain examples include, but are not limited to, the HIP API, the HSA API, and kernel dispatches.
For each domain, there are (often) various "operations", which can be used to restrict the callbacks
to a subset within the domain. For domains which correspond to APIs, the "operations" are the functions
which compose the API. If all operations in a domain should be traced, the `operations` and `operations_count`
parameters can be set to `nullptr` and `0`, respectively. If the tracing domain should be restricted to a subset
of operations, the tool library should specify a C-array of type `rocprofiler_tracing_operation_t` and the
size of the array for the `operations` and `operations_count` parameter.
Here are the parameters required to configure callback tracing services:
`rocprofiler_configure_callback_tracing_service` will return an error if a callback service for given context
and given domain is configured more than once. For example, if one only wanted to trace two functions within
the HIP runtime API, `hipGetDevice` and `hipSetDevice`, the following code would accomplish this objective:
- `kind`: A high-level specification of the services to be traced. This parameter is also known as "domain".
Domain examples include, but not limited to, the HIP API, HSA API, and kernel dispatches.
- `operations`: For each domain, there are often various `operations` that can be used to restrict the callbacks to a subset within the domain. For domains corresponding to APIs, the `operations` are the functions
composing the API. To trace all operations in a domain, set the `operations` and `operations_count`
parameters to `nullptr` and `0` respectively. To restrict the tracing domain to a subset
of operations, the tool library must specify a C-array of type `rocprofiler_tracing_operation_t` for `operations` and size of the array for the `operations_count` parameter.
`rocprofiler_configure_callback_tracing_service` returns an error if a callback service for the specified context and domain is configured more than once.
**Example:** To trace only two functions within
the HIP runtime API, `hipGetDevice` and `hipSetDevice`:
```cpp
{
@@ -55,7 +61,7 @@ the HIP runtime API, `hipGetDevice` and `hipSetDevice`, the following code would
}
```
But the following code would be invalid:
The following code returns error `ROCPROFILER_STATUS_ERROR_SERVICE_ALREADY_CONFIGURED` as the callback service is already configured:
```cpp
{
@@ -70,7 +76,7 @@ But the following code would be invalid:
for(auto op : operations)
{
// after the first iteration, will return ROCPROFILER_STATUS_ERROR_SERVICE_ALREADY_CONFIGURED
// after the first iteration, returns ROCPROFILER_STATUS_ERROR_SERVICE_ALREADY_CONFIGURED
rocprofiler_configure_callback_tracing_service(ctx,
ROCPROFILER_CALLBACK_TRACING_HIP_RUNTIME_API,
&op,
@@ -83,9 +89,9 @@ But the following code would be invalid:
}
```
## Callback Tracing Callback Function
## Callback tracing callback function
Rocprofiler-sdk callback tracing callback functions have the signature:
Here is the callback tracing callback function:
```cpp
typedef void (*rocprofiler_callback_tracing_cb_t)(rocprofiler_callback_tracing_record_t record,
@@ -93,12 +99,13 @@ typedef void (*rocprofiler_callback_tracing_cb_t)(rocprofiler_callback_tracing_r
void* callback_data)
```
The `record` parameter contains the information to uniquely identify a tracing record type and has the
following definition:
The parameters `record` and `user_data` are discussed here:
```cpp
typedef struct rocprofiler_callback_tracing_record_t
{
- `record`: Contains the information to uniquely identify a tracing record type. Here is the definition:
```cpp
typedef struct rocprofiler_callback_tracing_record_t
{
rocprofiler_context_id_t context_id;
rocprofiler_thread_id_t thread_id;
rocprofiler_correlation_id_t correlation_id;
@@ -106,26 +113,25 @@ typedef struct rocprofiler_callback_tracing_record_t
uint32_t operation;
rocprofiler_callback_phase_t phase;
void* payload;
} rocprofiler_callback_tracing_record_t;
```
} rocprofiler_callback_tracing_record_t;
```
The underlying type of `payload` field is typically unique to a domain and, less frequently, an operation.
For example, for the `ROCPROFILER_CALLBACK_TRACING_HIP_RUNTIME_API` and `ROCPROFILER_CALLBACK_TRACING_HIP_COMPILER_API`,
the payload must be casted to `rocprofiler_callback_tracing_hip_api_data_t*`, which contains the arguments
to the function and the return value when exiting the function. The payload field is a valid
pointer only during the invocation of the callback function(s).
The underlying type of `payload` field above is typically unique to a domain and, less frequently, an operation.
For example, for the `ROCPROFILER_CALLBACK_TRACING_HIP_RUNTIME_API` and `ROCPROFILER_CALLBACK_TRACING_HIP_COMPILER_API`,
the payload should be casted to `rocprofiler_callback_tracing_hip_api_data_t*` -- which will contain the arguments
to the function and (in the exit phase) the return value of the function. The payload field will only be a valid
pointer during the invocation of the callback function(s).
The `user_data` parameter can be used to store data in between callback phases. It is a unique for every
instance of an operation. For example, if the tool library wishes to store the timestamp of the
- `user_data`: Stores data in between callback phases. This value is unique for every
instance of an operation. For example, for a tool library to store the timestamp of the
`ROCPROFILER_CALLBACK_PHASE_ENTER` phase for the ensuing `ROCPROFILER_CALLBACK_PHASE_EXIT` callback,
this data can be stored in a method similar to below:
the data can be stored using:
```cpp
void
callback_func(rocprofiler_callback_tracing_record_t record,
```cpp
void
callback_func(rocprofiler_callback_tracing_record_t record,
rocprofiler_user_data_t* user_data,
void* cb_data)
{
{
auto ts = rocprofiler_timestamp_t{};
rocprofiler_get_timestamp(&ts);
@@ -142,26 +148,20 @@ callback_func(rocprofiler_callback_tracing_record_t record,
{
// ... etc. ...
}
}
```
}
```
The `callback_data` argument will be the value of `callback_args` passed to `rocprofiler_configure_callback_tracing_service`
in [the previous section](#subscribing-to-callback-tracing-services).
The `callback_data` is passed to `rocprofiler_configure_callback_tracing_service` as the value of `callback_args` to [subscribe to callback tracing services](#subscribing-to-callback-tracing-services).
## Callback Tracing Record
## Callback tracing record
The name of a tracing kind can be obtained via the `rocprofiler_query_callback_tracing_kind_name` function.
The name of an operation specific to a tracing kind can be obtained via the `rocprofiler_query_callback_tracing_kind_operation_name`
function. One can also iterate over all the callback tracing kinds and operations for each tracing kind via the
`rocprofiler_iterate_callback_tracing_kinds` and `rocprofiler_iterate_callback_tracing_kind_operations` functions.
Lastly, for a given `rocprofiler_callback_tracing_record_t` object, rocprofiler-sdk supports generically iterating over
the arguments of the payload field for many domains.
To obtain the name of the `kind` of tracing, you can use `rocprofiler_query_callback_tracing_kind_name` function and to obtain the name of an `operation` specific to a tracing kind, use `rocprofiler_query_callback_tracing_kind_operation_name`
function. To iterate over all the callback tracing kinds and operations for each tracing kind, use `rocprofiler_iterate_callback_tracing_kinds` and `rocprofiler_iterate_callback_tracing_kind_operations` functions.
As mentioned above, within the `rocprofiler_callback_tracing_record_t` object,
an opaque `void* payload` is provided for accessing domain specific information.
The data types generally follow the naming convention of `rocprofiler_callback_tracing_<DOMAIN>_data_t`,
e.g., for the tracing kinds `ROCPROFILER_BUFFER_TRACING_HSA_{CORE,AMD_EXT,IMAGE_EXT,FINALIZE_EXT}_API`,
the payload should be casted to `rocprofiler_callback_tracing_hsa_api_data_t*`:
Lastly, for a specified `rocprofiler_callback_tracing_record_t` object, ROCprofiler-SDK supports generically iterating over the arguments of the payload field for many domains. Within the `rocprofiler_callback_tracing_record_t` object, the domain-specific information is available in
an opaque `void* payload`.
The data types generally follow the naming convention of `rocprofiler_callback_tracing_<DOMAIN>_data_t`. For example, for the tracing kinds `ROCPROFILER_BUFFER_TRACING_HSA_{CORE,AMD_EXT,IMAGE_EXT,FINALIZE_EXT}_API`,
cast the payload to `rocprofiler_callback_tracing_hsa_api_data_t*`:
```cpp
void
@@ -205,7 +205,7 @@ callback_func(rocprofiler_callback_tracing_record_t record,
}
```
### Sample `rocprofiler_iterate_callback_tracing_kind_operation_args`
**Example:** Iterating over all the callback tracing kinds and operations for each tracing kind using `rocprofiler_iterate_callback_tracing_kind_operation_args`:
```cpp
int
@@ -263,7 +263,7 @@ callback_func(rocprofiler_callback_tracing_record_t record,
}
```
Sample Output:
**Sample output:**
```console
@@ -283,55 +283,57 @@ Sample Output:
4: hipStream_t* stream = 0x25dfcf0
```
## Code Object Tracing
## Code object tracing
The code object tracing service is a critical component for obtaining information regarding
asynchronous activity on the GPU. The `rocprofiler_callback_tracing_code_object_load_data_t`
payload (kind=`ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT`, operation=`ROCPROFILER_CODE_OBJECT_LOAD`)
provides a unique identifier for a bundle of one or more GPU kernel symbols which have been loaded
for a specific GPU agent. For example, if your application is leveraging a multi-GPU system system
containing 4 Vega20 GPUs and 4 MI100 GPUs, there will at least 8 code objects loaded: one code
object for each GPU. Each code object will be associated with a set of kernel symbols:
the `rocprofiler_callback_tracing_code_object_kernel_symbol_register_data_t` payload
provides a unique identifier for a bundle of one or more GPU kernel symbols that are loaded
for a specific GPU agent. For example, if your application leverages a multi-GPU system
consisting of four Vega20 GPUs and four MI100 GPUs, at least eight code objects will be loaded: one code
object for each GPU. Each code object will be associated with a set of kernel symbols.
The `rocprofiler_callback_tracing_code_object_kernel_symbol_register_data_t` payload
(kind=`ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT`, operation=`ROCPROFILER_CODE_OBJECT_DEVICE_KERNEL_SYMBOL_REGISTER`)
provides a globally unique identifier for the specific kernel symbol along with the kernel name and
several other static properties of the kernel (e.g. scratch size, scalar general purpose register count, etc.).
Note: two otherwise identical kernel symbols (same kernel name, scratch size, etc.) which are part of
otherwise identical code objects but the code objects are loaded for different GPU agents ***will*** have unique
kernel identifiers. Furthermore, if the same code object (and it's kernel symbols) are unloaded and then
re-loaded, that code object and all of it's kernel symbols ***will*** be given new unique identifiers.
several other static properties of the kernel such as scratch size, scalar general purpose register count, and so on.
In general, when a code object is loaded and unloaded, here is the sequence of events:
:::{note}
The kernel identifiers for two identical kernel symbols with the same properties (kernel name, scratch size, and so on) that are part of similar code objects loaded for different GPU agents will still be unique. Furthermore, the identifier for a code object and its kernel symbols after being unloaded and then
reloaded, will also be unique.
:::
1. Callback: code object load
Here is the general sequence of events when a code object is loaded and unloaded:
1. Callback: load code object
- kind=`ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT`
- operation=`ROCPROFILER_CODE_OBJECT_LOAD`
- phase=`ROCPROFILER_CALLBACK_PHASE_LOAD`
2. Callback: kernel symbol load
2. Callback: load kernel symbol
- kind=`ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT`
- operation=`ROCPROFILER_CODE_OBJECT_DEVICE_KERNEL_SYMBOL_REGISTER`
- phase=`ROCPROFILER_CALLBACK_PHASE_LOAD`
- Repeats for each kernel symbol in code object
3. Application Execution
4. Callback: kernel symbol unload
3. Execute application
4. Callback: unload kernel symbol
- kind=`ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT`
- operation=`ROCPROFILER_CODE_OBJECT_DEVICE_KERNEL_SYMBOL_REGISTER`
- phase=`ROCPROFILER_CALLBACK_PHASE_UNLOAD`
- Repeats for each kernel symbol in code object
5. Callback: code object unload
5. Callback: unload code object
- kind=`ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT`
- operation=`ROCPROFILER_CODE_OBJECT_LOAD`
- phase=`ROCPROFILER_CALLBACK_PHASE_UNLOAD`
Note: rocprofiler-sdk does not provide an interface to query this information outside of the
code object tracing service. If you wish to be able to associate kernel names with kernel tracing records,
a tool is personally responsible for making a copy of the relevant information when the code objects and
kernel symbol are loaded (however, any constant string fields like the (`const char* kernel_name` field)
need not to be copied, these are guaranteed to be valid pointers until after rocprofiler-sdk finalization).
If a tool decides to delete their copy of the data associated with a given code object or kernel symbol
:::{note}
ROCprofiler-SDK doesn't provide an interface to query information outside of the
code object tracing service. If you wish to associate kernel names with kernel tracing records,
the tool must be configured to create a copy of the relevant information when the code objects and
kernel symbol are loaded. However, any constant string fields like `const char* kernel_name`
don't need to be copied as these are guaranteed to be valid pointers until after ROCprofiler-SDK finalization.
If a tool decides to delete its copy of the data associated with a code object or kernel symbol
identifier when the code object and kernel symbols are unloaded, it is highly recommended to flush
any/all buffers which might contain references to that code object or kernel symbol identifiers before
all buffers that might contain references to that code object or kernel symbol identifier before
deleting the associated data.
:::
For a sample of code object tracing, please see the `samples/code_object_tracing` example in the
[rocprofiler-sdk GitHub repository](https://github.com/ROCm/rocprofiler-sdk).
For a sample of code object tracing, see [samples/code_object_tracing](https://github.com/ROCm/rocprofiler-sdk/tree/amd-mainline/samples/code_object_tracing).