Files
rocm-systems/source/include/rocprofiler/buffer_tracing.h
T
Jonathan R. Madsen 3082288a25 Code object, kernel dispatch, and memory copy tracing (#177)
* Update samples/api_buffered_tracing

- external correlation id
- support ROCPROFILER_BUFFER_TRACING_KERNEL_DISPATCH

* Update lib/rocprofiler/context.cpp

- update alternative get_active_contexts paradigm

* Update lib/rocprofiler/external_correlation.cpp

- inherit correlation id from main thread

* Update lib/rocprofiler/hsa/queue.*

- typedef changes
- rocprofiler_packet union
- modify Queue::queue_info_session_t
  - use rocprofiler_packet
  - add thread id
  - add kernel id
  - add correlation id
- out of line definitions
- AsyncSignalHandler function update
  - handle kernel dispatch tracing
- Move CreateBarrierPacket and AddVendorSpecificPacket to lambdas
- handle contexts

* Update lib/rocprofiler/hsa/hsa.cpp

- remove unnecessary log function
- use new get_active_contexts paradigm
- use new correlation id updates

* Update AgentCache and kernel dispatch record

- include const rocprofiler_agent_t* in rocprofiler_buffer_tracing_kernel_dispatch_record_t
- AgentCache::get_rocp_agent returns const pointer

* Replace ROCPROFILER_SERVICE_ with ROCPROFILER_

* source formatting

* Code Object Tracing

- include/rocprofiler/callback_tracing.h
  - remove rocprofiler_callback_tracing_code_object_unload_data_t
  - remove rocprofiler_callback_tracing_code_object_kernel_symbol_register_data_t
- include/rocprofiler/fwd.h
  - remove ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT_UNLOAD
  - remove ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT_DEVICE_KERNEL_SYMBOL_UNREGISTER
- lib/common/utility.hpp
  - assert_public_api_struct_properties()
  - init_public_api_struct(...)
- lib/rocprofiler/registration.cpp
  - invoke hsa::code_object_init
- lib/rocprofiler/hsa/CMakeLists.txt
  - compile code_object code
- lib/rocprofiler/hsa/code_object.{hpp,cpp}
  - tracing code object load/unload
- lib/rocprofiler/hsa/queue.cpp
  - get_kernel_id

* Update lib/rocprofiler/hsa/hsa.cpp

- fix should_wrap_functor logic (which was not handling callback_tracer + buffered_tracer properly)

* Update lib/rocprofiler/hsa/queue.cpp

- fix rocprofiler_buffer_tracing_kernel_dispatch_record_t construction

* Update samples/api_buffered_tracing/client.cpp

- print kernel names

* Move samples/apps to tests/apps

* Update lib/rocprofiler/hsa/code_object.cpp

- ensure unload callbacks when application is exiting
- support user data in between load/unload callbacks

* Update lib/rocprofiler/hsa/queue.{hpp,cpp}

- store contexts and external correlation ids in queue_info_session
- reduce signal_limiter to 96 to fix hangs
- fix support for kernel tracing and async memory copies

* Add lib/common/scope_destructor.hpp

- similar to static_cleanup_wrapper but different

* Update include/rocprofiler/buffer_tracing.h

- update rocprofiler_buffer_tracing_memory_copy_record_t
- remove operation: user can figure that out from correlation id
- add kernel id
- add rocprofiler agent id

* Update include/rocprofiler/callback_tracing.h

- fix data type of load_delta field in code object
- remove rocp_agent from kernel_symbol_register_data_t (known via code_object_id)

* Add samples/code_object_tracing

- sample demonstrating code object tracing

* Update samples

- minor tweak to print_call_stack

* Update lib/rocprofiler/hsa/code_object.cpp

- flip ordering of unload callbacks for code object unloading and kernel symbol deregistering

* clang-tidy fixes

* Update lib/rocprofiler/hsa/code_object.cpp

- fix heap-use-after-free issue with code object

* Update include/rocprofiler/external_correlation.h

- update documentation to include info about default value of external correlation value

* Use common::container::small_vector for contexts

- small_vector<const context*> is an ideal data structure for array of active contexts

* Update context handling for code object unload

- code object unload is only called for contexts which received the load callback

* Update samples

- improve ROCPROFILER_CALL macro to include status string
- api_buffered_tracing handles ROCPROFILER_STATUS_ERROR_BUFFER_BUSY

* Code object shutdown

- ensure code object callbacks are invoked prior to finalizing

* Update lib/common (memory allocators)

- added lib/common/memory folder with allocators

* Add lib/rocprofiler/allocator.*

- rocprofiler::allocator::static_data_allocator
  - special allocator for static data which finalizes before any data gets destroyed
- rocprofiler::allocator::unique_static_ptr_t
  - unique_ptr that uses static data deleter (ensure finalize is called)

* Update lib/rocprofiler/buffer.cpp

- flush checks fini status
- use unique_static_ptr_t

* Update lib/rocprofiler/internal_threading.*

- change meaning of thread_pool_t and task_group_t
- improve finalization to prevent data races and heap-use-after-free

* Update lib/rocprofiler/registration.cpp

- use static_data_allocator for client_library vector

* Update lib/rocprofiler/context/context.*

- use allocator::unique_static_ptr_t

* Update lib/rocprofiler/allocator.cpp

- avoid deadlock in deleter<static_data>::operator()

* Update lib/rocprofiler/registration.cpp

- avoid deadlock in rocprofiler::registration::finalize()

* Update lib/rocprofiler/hsa/code_object.cpp

- suppress duplicate reporting of code-object/kernel-symbol load/unload

* Update leak sanitizer suppressions

- __new_exitfn (via stdlib/cxa_atexit.c leaks
2023-11-13 22:30:15 -06:00

334 строки
14 KiB
C

// MIT License
//
// Copyright (c) 2023 ROCm Developer Tools
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include <rocprofiler/agent.h>
#include <rocprofiler/defines.h>
#include <rocprofiler/fwd.h>
ROCPROFILER_EXTERN_C_INIT
/**
* @defgroup BUFFER_TRACING_SERVICE Asynchronous Tracing Service
* @brief Receive callbacks for batches of records from an internal (background) thread
*
* @{
*/
/**
* @brief ROCProfiler Buffer HSA API Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_tracing_operation_t operation; // rocprofiler/hsa.h
rocprofiler_timestamp_t start_timestamp;
rocprofiler_timestamp_t end_timestamp;
rocprofiler_thread_id_t thread_id;
} rocprofiler_buffer_tracing_hsa_api_record_t;
/**
* @brief ROCProfiler Buffer HIP API Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_tracing_operation_t operation; // rocprofiler/hip.h
rocprofiler_timestamp_t start_timestamp;
rocprofiler_timestamp_t end_timestamp;
rocprofiler_thread_id_t thread_id;
} rocprofiler_buffer_tracing_hip_api_record_t;
/**
* @brief ROCProfiler Buffer Marker Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_tracing_operation_t operation; // rocprofiler/marker.h
rocprofiler_timestamp_t timestamp;
rocprofiler_thread_id_t thread_id;
uint64_t marker_id; // rocprofiler_marker_id_t
// const char* message; // (Need Review?)
} rocprofiler_buffer_tracing_marker_record_t;
/**
* @brief ROCProfiler Buffer Memory Copy Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_timestamp_t start_timestamp;
rocprofiler_timestamp_t end_timestamp;
rocprofiler_agent_id_t agent_id;
rocprofiler_queue_id_t queue_id;
rocprofiler_kernel_id_t kernel_id;
} rocprofiler_buffer_tracing_memory_copy_record_t;
/**
* @brief ROCProfiler Buffer Kernel Dispatch Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_timestamp_t start_timestamp;
rocprofiler_timestamp_t end_timestamp;
rocprofiler_agent_id_t agent_id;
rocprofiler_queue_id_t queue_id;
rocprofiler_kernel_id_t kernel_id;
uint32_t private_segment_size;
uint32_t group_segment_size;
rocprofiler_dim3_t workgroup_size;
rocprofiler_dim3_t grid_size;
} rocprofiler_buffer_tracing_kernel_dispatch_record_t;
/**
* @brief ROCProfiler Buffer Page Migration Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_timestamp_t start_timestamp;
rocprofiler_timestamp_t end_timestamp;
rocprofiler_queue_id_t queue_id;
// Not Sure What is the info needed here?
} rocprofiler_buffer_tracing_page_migration_record_t;
/**
* @brief ROCProfiler Buffer Scratch Memory Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_timestamp_t start_timestamp;
rocprofiler_timestamp_t end_timestamp;
rocprofiler_queue_id_t queue_id;
// Not Sure What is the info needed here?
} rocprofiler_buffer_tracing_scratch_memory_record_t;
/**
* @brief ROCProfiler Buffer Queue Scheduling Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
rocprofiler_timestamp_t start_timestamp;
rocprofiler_timestamp_t end_timestamp;
rocprofiler_queue_id_t queue_id;
// Not Sure What is the info needed here?
} rocprofiler_buffer_tracing_queue_scheduling_record_t;
/**
* @brief ROCProfiler Code Object Tracer Buffer Record.
*
* We need to guarantee that these records are in the buffer before the
* corresponding Exit Phase API calls are called.
*/
// typedef struct {
// rocprofiler_buffer_tracing_record_header_t header;
// rocprofiler_tracing_code_object_kind_id_t kind;
// } rocprofiler_buffer_tracing_code_object_header_t;
/**
* @brief ROCProfiler Code Object Load Tracer Buffer Record.
*
*/
// typedef struct {
// rocprofiler_buffer_tracing_code_object_header_t header;
// uint64_t load_base; // code object load base
// uint64_t load_size; // code object load size
// const char *uri; // URI string (NULL terminated)
// rocprofiler_timestamp_t timestamp;
// // uint32_t storage_type; // code object storage type (Need Review?)
// // int storage_file; // origin file descriptor (Need Review?)
// // uint64_t memory_base; // origin memory base (Need Review?)
// // uint64_t memory_size; // origin memory size (Need Review?)
// // uint64_t load_delta; // code object load delta (Need Review?)
// } rocprofiler_buffer_tracing_code_object_load_record_t;
/**
* @brief ROCProfiler Code Object UnLoad Tracer Buffer Record.
*
*/
// typedef struct {
// rocprofiler_buffer_tracing_code_object_header_t header;
// uint64_t load_base; // code object load base
// rocprofiler_timestamp_t timestamp;
// } rocprofiler_buffer_tracing_code_object_unload_record_t;
/**
* @brief ROCProfiler Code Object Kernel Symbol Tracer Buffer Record.
*
*/
// typedef struct {
// rocprofiler_buffer_tracing_code_object_header_t header;
// const char *kernel_name; // kernel name string (NULL terminated)
// uint64_t kernel_descriptor; // kernel descriptor (Need to be changed from
// // uint64_t to ::rocprofiler_address_t)
// // rocprofiler_timestamp_t timestamp; // (Need Review?)
// } rocprofiler_buffer_tracing_code_object_kernel_symbol_record_t;
/**
* @brief ROCProfiler Buffer External Correlation Tracer Record.
*/
typedef struct
{
uint64_t size;
rocprofiler_service_buffer_tracing_kind_t kind;
rocprofiler_correlation_id_t correlation_id;
} rocprofiler_buffer_tracing_correlation_record_t;
/**
* @brief Callback function for mapping @ref rocprofiler_service_buffer_tracing_kind_t ids to
* string names. @see rocprofiler_iterate_buffer_trace_kind_names.
*/
typedef int (*rocprofiler_buffer_tracing_kind_cb_t)(rocprofiler_service_buffer_tracing_kind_t kind,
void* data);
/**
* @brief Callback function for mapping the operations of a given @ref
* rocprofiler_service_buffer_tracing_kind_t to string names. @see
* rocprofiler_iterate_buffer_trace_kind_operation_names.
*/
typedef int (*rocprofiler_buffer_tracing_kind_operation_cb_t)(
rocprofiler_service_buffer_tracing_kind_t kind,
uint32_t operation,
void* data);
/**
* @brief Configure Buffer Tracing Service.
*
* @param [in] context_id
* @param [in] kind
* @param [in] operations
* @param [in] operations_count
* @param [in] buffer_id
* @return ::rocprofiler_status_t
*
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_configure_buffer_tracing_service(rocprofiler_context_id_t context_id,
rocprofiler_service_buffer_tracing_kind_t kind,
rocprofiler_tracing_operation_t* operations,
size_t operations_count,
rocprofiler_buffer_id_t buffer_id);
/**
* @brief Query the name of the buffer tracing kind. The name retrieved from this function is a
* string literal that is encoded in the read-only section of the binary (i.e. it is always
* "allocated" and never "deallocated").
*
* @param [in] kind Buffer tracing domain
* @param [out] name If non-null and the name is a constant string that does not require dynamic
* allocation, this paramter will be set to the address of the string literal, otherwise it will
* be set to nullptr
* @param [out] name_len If non-null, this will be assigned the length of the name (regardless of
* the name is a constant string or requires dynamic allocation)
* @return ::rocprofiler_status_t
* @retval ::ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND Returned if the domain id is not valid
* @retval ::ROCPROFILER_STATUS_SUCCESS Returned if a valid domain, regardless if there is a
* constant string or not.
*/
rocprofiler_status_t
rocprofiler_query_buffer_tracing_kind_name(rocprofiler_service_buffer_tracing_kind_t kind,
const char** name,
uint64_t* name_len) ROCPROFILER_API;
/**
* @brief Query the name of the buffer tracing kind. The name retrieved from this function is a
* string literal that is encoded in the read-only section of the binary (i.e. it is always
* "allocated" and never "deallocated").
*
* @param [in] kind Buffer tracing domain
* @param [in] operation Enumeration id value which maps to a specific API function or event type
* @param [out] name If non-null and the name is a constant string that does not require dynamic
* allocation, this paramter will be set to the address of the string literal, otherwise it will
* be set to nullptr
* @param [out] name_len If non-null, this will be assigned the length of the name (regardless of
* the name is a constant string or requires dynamic allocation)
* @return ::rocprofiler_status_t
* @retval ::ROCPROFILER_STATUS_ERROR_KIND_NOT_FOUND An invalid domain id
* @retval ::ROCPROFILER_STATUS_ERROR_OPERATION_NOT_FOUND The operation number is not recognized for
* the given domain
* @retval ::ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED Rocprofiler does not support providing the
* operation name within this domain
* @retval ::ROCPROFILER_STATUS_SUCCESS Valid domain and operation, regardless of whether there is a
* constant string or not.
*/
rocprofiler_status_t
rocprofiler_query_buffer_tracing_kind_operation_name(rocprofiler_service_buffer_tracing_kind_t kind,
uint32_t operation,
const char** name,
uint64_t* name_len) ROCPROFILER_API;
/**
* @brief Iterate over all the mappings of the buffer tracing kinds and get a buffer with the id
* mapped to a constant string. The strings provided in the arg will be valid pointers for the
* entire duration of the program. It is recommended to call this function once and cache this data
* in the client instead of making multiple on-demand calls.
*
* @param [in] callback Callback function invoked for each enumeration value in @ref
* rocprofiler_service_buffer_tracing_kind_t with the exception of the `NONE` and `LAST` values.
* @param [in] data User data passed back into the callback
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_iterate_buffer_tracing_kinds(rocprofiler_buffer_tracing_kind_cb_t callback, void* data)
ROCPROFILER_NONNULL(1);
/**
* @brief Iterates over all the operations for a given @ref
* rocprofiler_service_buffer_tracing_kind_t and invokes the callback with the kind and operation
* id. This is useful to build a map of the operation names during tool initialization instead of
* querying rocprofiler everytime in the callback hotpath.
*
* @param [in] kind which buffer tracing kind operations to iterate over
* @param [in] callback Callback function invoked for each operation associated with @ref
* rocprofiler_service_buffer_tracing_kind_t with the exception of the `NONE` and `LAST` values.
* @param [in] data User data passed back into the callback
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_iterate_buffer_tracing_kind_operations(
rocprofiler_service_buffer_tracing_kind_t kind,
rocprofiler_buffer_tracing_kind_operation_cb_t callback,
void* data) ROCPROFILER_NONNULL(2);
/** @} */
ROCPROFILER_EXTERN_C_FINI