Add support for RCCL tracing (#1047)

* [Draft]: Add support for RCCL tracing

Address comments

* [Draft]: Add support for RCCL tracing

Address PR comments, changes from RCCL upstream

* Add RCCL library table registration

Working on adding support to rocprofiler-register

* Support compilation w/o <rccl/amd_detail/api_trace.h>

- dummy api_trace.h header
- return ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED when RCCL does not have api_trace.h header

* RCCL API tracing tool support

- add to rocprofv3
- add to json-tool

---------

Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
Bu işleme şunda yer alıyor:
Mythreya
2024-09-11 22:42:58 -07:00
işlemeyi yapan: GitHub
ebeveyn 72cbcedc9e
işleme 2a146259c7
43 değiştirilmiş dosya ile 2270 ekleme ve 30 silme
+20
Dosyayı Görüntüle
@@ -295,3 +295,23 @@ target_link_libraries(rocprofiler-elfio INTERFACE elfio::elfio)
# ----------------------------------------------------------------------------------------#
target_link_libraries(rocprofiler-otf2 INTERFACE otf2::otf2)
# ----------------------------------------------------------------------------------------#
#
# RCCL
#
# ----------------------------------------------------------------------------------------#
find_package(
rccl
REQUIRED
CONFIG
HINTS
${rocm_version_DIR}
${ROCM_PATH}
PATHS
${rocm_version_DIR}
${ROCM_PATH}
PATH_SUFFIXES
lib/cmake/rccl)
rocprofiler_config_nolink_target(rocprofiler-rccl-nolink rccl::rccl)
+2
Dosyayı Görüntüle
@@ -82,3 +82,5 @@ rocprofiler_add_interface_library(
rocprofiler_add_interface_library(
rocprofiler-hsakmt-nolink "rocprofiler-hsakmt without linking to HSAKMT library"
IMPORTED)
rocprofiler_add_interface_library(rocprofiler-rccl-nolink
"RCCL headers without linking to RCCL library" IMPORTED)
+10 -2
Dosyayı Görüntüle
@@ -141,13 +141,13 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins
aggregate_tracing_options,
"-r",
"--runtime-trace",
help="Collect tracing data for HIP runtime API, Marker (ROCTx) API, Memory operations (copies and scratch), and Kernel dispatches. Similar to --sys-trace but without tracing HIP compiler API and the underlying HSA API.",
help="Collect tracing data for HIP runtime API, Marker (ROCTx) API, RCCL API, Memory operations (copies and scratch), and Kernel dispatches. Similar to --sys-trace but without tracing HIP compiler API and the underlying HSA API.",
)
add_parser_bool_argument(
aggregate_tracing_options,
"-s",
"--sys-trace",
help="Collect tracing data for HIP API, HSA API, Marker (ROCTx) API, Memory operations (copies and scratch), and Kernel dispatches.",
help="Collect tracing data for HIP API, HSA API, Marker (ROCTx) API, RCCL API, Memory operations (copies and scratch), and Kernel dispatches.",
)
basic_tracing_options = parser.add_argument_group("Basic tracing options")
@@ -183,6 +183,11 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins
"--hsa-trace",
help="For collecting HSA Traces (core + amd + image + finalizer)",
)
add_parser_bool_argument(
basic_tracing_options,
"--rccl-trace",
help="For collecting RCCL Traces",
)
extended_tracing_options = parser.add_argument_group("Granular tracing options")
@@ -654,6 +659,7 @@ def run(app_args, args, **kwargs):
"kernel_trace",
"memory_copy_trace",
"scratch_memory_trace",
"rccl_trace",
):
setattr(args, itr, True)
@@ -664,6 +670,7 @@ def run(app_args, args, **kwargs):
"kernel_trace",
"memory_copy_trace",
"scratch_memory_trace",
"rccl_trace",
):
setattr(args, itr, True)
@@ -686,6 +693,7 @@ def run(app_args, args, **kwargs):
["hsa_image_trace", "HSA_IMAGE_EXT_API_TRACE"],
["hsa_finalizer_trace", "HSA_FINALIZER_EXT_API_TRACE"],
["marker_trace", "MARKER_API_TRACE"],
["rccl_trace", "RCCL_API_TRACE"],
["kernel_trace", "KERNEL_TRACE"],
["memory_copy_trace", "MEMORY_COPY_TRACE"],
["scratch_memory_trace", "SCRATCH_MEMORY_TRACE"],
+18
Dosyayı Görüntüle
@@ -147,6 +147,24 @@ typedef struct
/// ::rocprofiler_marker_name_api_id_t
} rocprofiler_buffer_tracing_marker_api_record_t;
/**
* @brief ROCProfiler Buffer RCCL API Record.
*/
typedef struct
{
uint64_t size; ///< size of this struct
rocprofiler_buffer_tracing_kind_t kind;
rocprofiler_tracing_operation_t operation;
rocprofiler_correlation_id_t correlation_id; ///< correlation ids for record
rocprofiler_timestamp_t start_timestamp; ///< start time in nanoseconds
rocprofiler_timestamp_t end_timestamp; ///< end time in nanoseconds
rocprofiler_thread_id_t thread_id; ///< id for thread generating this record
/// @var kind
/// @brief ::ROCPROFILER_CALLBACK_TRACING_RCCL_API,
/// @brief Specification of the API function, e.g., ::rocprofiler_rccl_api_id_t,
} rocprofiler_buffer_tracing_rccl_api_record_t;
/**
* @brief ROCProfiler Buffer Memory Copy Tracer Record.
*/
+11
Dosyayı Görüntüle
@@ -27,6 +27,7 @@
#include <rocprofiler-sdk/hip.h>
#include <rocprofiler-sdk/hsa.h>
#include <rocprofiler-sdk/marker.h>
#include <rocprofiler-sdk/rccl.h>
#include <hsa/hsa.h>
#include <hsa/hsa_amd_tool.h>
@@ -87,6 +88,16 @@ typedef struct
rocprofiler_marker_api_retval_t retval;
} rocprofiler_callback_tracing_marker_api_data_t;
/**
* @brief ROCProfiler RCCL API Callback Data.
*/
typedef struct
{
uint64_t size; ///< size of this struct
rocprofiler_rccl_api_args_t args;
rocprofiler_rccl_api_retval_t retval;
} rocprofiler_callback_tracing_rccl_api_data_t;
/**
* @brief ROCProfiler Code Object Load Tracer Callback Record.
*/
+2
Dosyayı Görüntüle
@@ -77,6 +77,7 @@ struct perfetto_category;
ROCPROFILER_DEFINE_CATEGORY(category, hsa_api, "HSA API function")
ROCPROFILER_DEFINE_CATEGORY(category, hip_api, "HIP API function")
ROCPROFILER_DEFINE_CATEGORY(category, marker_api, "Marker API region")
ROCPROFILER_DEFINE_CATEGORY(category, rccl_api, "RCCL API function")
ROCPROFILER_DEFINE_CATEGORY(category, kernel_dispatch, "GPU kernel dispatch")
ROCPROFILER_DEFINE_CATEGORY(category, memory_copy, "Async memory copy")
@@ -84,6 +85,7 @@ ROCPROFILER_DEFINE_CATEGORY(category, memory_copy, "Async memory copy")
ROCPROFILER_PERFETTO_CATEGORY(category::hsa_api), \
ROCPROFILER_PERFETTO_CATEGORY(category::hip_api), \
ROCPROFILER_PERFETTO_CATEGORY(category::marker_api), \
ROCPROFILER_PERFETTO_CATEGORY(category::rccl_api), \
ROCPROFILER_PERFETTO_CATEGORY(category::kernel_dispatch), \
ROCPROFILER_PERFETTO_CATEGORY(category::memory_copy)
+23
Dosyayı Görüntüle
@@ -327,6 +327,22 @@ save(ArchiveT& ar, rocprofiler_callback_tracing_memory_copy_data_t data)
ROCP_SDK_SAVE_DATA_FIELD(bytes);
}
template <typename ArchiveT>
void
save(ArchiveT& ar, rocprofiler_rccl_api_retval_t data)
{
ROCP_SDK_SAVE_DATA_FIELD(ncclResult_t_retval);
}
template <typename ArchiveT>
void
save(ArchiveT& ar, rocprofiler_callback_tracing_rccl_api_data_t data)
{
ROCP_SDK_SAVE_DATA_FIELD(size);
// ROCP_SDK_SAVE_DATA_FIELD(args);
ROCP_SDK_SAVE_DATA_FIELD(retval);
}
template <typename ArchiveT>
void
save(ArchiveT& ar, rocprofiler_profile_counting_dispatch_data_t data)
@@ -405,6 +421,13 @@ save(ArchiveT& ar, rocprofiler_buffer_tracing_marker_api_record_t data)
save_buffer_tracing_api_record(ar, data);
}
template <typename ArchiveT>
void
save(ArchiveT& ar, rocprofiler_buffer_tracing_rccl_api_record_t data)
{
save_buffer_tracing_api_record(ar, data);
}
template <typename ArchiveT>
void
save(ArchiveT& ar, rocprofiler_buffer_tracing_kernel_dispatch_record_t data)
+1
Dosyayı Görüntüle
@@ -66,6 +66,7 @@ typedef enum // NOLINT(performance-enum-size)
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_MEMORY_COPY,
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_KERNEL_DISPATCH,
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_SCRATCH_MEMORY,
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_RCCL_API,
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_LAST,
} rocprofiler_external_correlation_id_request_kind_t;
+6 -2
Dosyayı Görüntüle
@@ -169,6 +169,7 @@ typedef enum // NOLINT(performance-enum-size)
ROCPROFILER_CALLBACK_TRACING_SCRATCH_MEMORY, ///< @see ::rocprofiler_scratch_memory_operation_t
ROCPROFILER_CALLBACK_TRACING_KERNEL_DISPATCH, ///< Callbacks for kernel dispatches
ROCPROFILER_CALLBACK_TRACING_MEMORY_COPY, ///< @see ::rocprofiler_memory_copy_operation_t
ROCPROFILER_CALLBACK_TRACING_RCCL_API, ///< @RCCL tracing
ROCPROFILER_CALLBACK_TRACING_LAST,
} rocprofiler_callback_tracing_kind_t;
@@ -193,6 +194,7 @@ typedef enum // NOLINT(performance-enum-size)
ROCPROFILER_BUFFER_TRACING_PAGE_MIGRATION, ///< Buffer page migration info
ROCPROFILER_BUFFER_TRACING_SCRATCH_MEMORY, ///< Buffer scratch memory reclaimation info
ROCPROFILER_BUFFER_TRACING_CORRELATION_ID_RETIREMENT, ///< Correlation ID in no longer in use
ROCPROFILER_BUFFER_TRACING_RCCL_API, ///< RCCL tracing
ROCPROFILER_BUFFER_TRACING_LAST,
} rocprofiler_buffer_tracing_kind_t;
@@ -350,7 +352,8 @@ typedef enum
ROCPROFILER_HSA_LIBRARY = (1 << 1),
ROCPROFILER_HIP_LIBRARY = (1 << 2),
ROCPROFILER_MARKER_LIBRARY = (1 << 3),
ROCPROFILER_LIBRARY_LAST = ROCPROFILER_MARKER_LIBRARY,
ROCPROFILER_RCCL_LIBRARY = (1 << 4),
ROCPROFILER_LIBRARY_LAST = ROCPROFILER_RCCL_LIBRARY,
} rocprofiler_runtime_library_t;
/**
@@ -365,7 +368,8 @@ typedef enum
ROCPROFILER_MARKER_CORE_TABLE = (1 << 3),
ROCPROFILER_MARKER_CONTROL_TABLE = (1 << 4),
ROCPROFILER_MARKER_NAME_TABLE = (1 << 5),
ROCPROFILER_TABLE_LAST = ROCPROFILER_MARKER_NAME_TABLE,
ROCPROFILER_RCCL_TABLE = (1 << 6),
ROCPROFILER_TABLE_LAST = ROCPROFILER_RCCL_TABLE,
} rocprofiler_intercept_table_t;
/**
+27
Dosyayı Görüntüle
@@ -0,0 +1,27 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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-sdk/rccl/api_args.h>
#include <rocprofiler-sdk/rccl/api_id.h>
#include <rocprofiler-sdk/rccl/table_id.h>
+308
Dosyayı Görüntüle
@@ -0,0 +1,308 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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-sdk/defines.h>
#include <rocprofiler-sdk/version.h>
#include <rccl/rccl.h>
#include <stdint.h>
ROCPROFILER_EXTERN_C_INIT
// Empty struct has a size of 0 in C but size of 1 in C++.
// This struct is added to the union members which represent
// functions with no arguments to ensure ABI compatibility
typedef struct rocprofiler_rccl_api_no_args
{
char empty;
} rocprofiler_rccl_api_no_args;
typedef union rocprofiler_rccl_api_retval_t
{
int32_t ncclResult_t_retval;
const char* const_charp_retval;
} rocprofiler_rccl_api_retval_t;
typedef union rocprofiler_rccl_api_args_t
{
struct
{
const void* sendbuff;
void* recvbuff;
size_t sendcount;
ncclDataType_t datatype;
ncclComm_t comm;
hipStream_t stream;
} ncclAllGather;
struct
{
const void* sendbuff;
void* recvbuff;
size_t count;
ncclDataType_t datatype;
ncclRedOp_t op;
struct ncclComm* comm;
hipStream_t stream;
} ncclAllReduce;
struct
{
const void* sendbuff;
void* recvbuff;
size_t count;
ncclDataType_t datatype;
ncclComm_t comm;
hipStream_t stream;
} ncclAllToAll;
struct
{
const void* sendbuff;
const size_t* sendcounts;
const size_t* sdispls;
void* recvbuff;
const size_t* recvcounts;
const size_t* rdispls;
ncclDataType_t datatype;
ncclComm_t comm;
hipStream_t stream;
} ncclAllToAllv;
struct
{
const void* sendbuff;
void* recvbuff;
size_t count;
ncclDataType_t datatype;
int root;
ncclComm_t comm;
hipStream_t stream;
} ncclBroadcast;
struct
{
const void* sendbuff;
void* recvbuff;
size_t sendcount;
ncclDataType_t datatype;
int root;
ncclComm_t comm;
hipStream_t stream;
} ncclGather;
struct
{
const void* sendbuff;
void* recvbuff;
size_t count;
ncclDataType_t datatype;
ncclRedOp_t op;
int root;
ncclComm_t comm;
hipStream_t stream;
} ncclReduce;
struct
{
const void* sendbuff;
void* recvbuff;
size_t recvcount;
ncclDataType_t datatype;
ncclRedOp_t op;
struct ncclComm* comm;
hipStream_t stream;
} ncclReduceScatter;
struct
{
const void* sendbuff;
void* recvbuff;
size_t recvcount;
ncclDataType_t datatype;
int root;
ncclComm_t comm;
hipStream_t stream;
} ncclScatter;
struct
{
const void* sendbuff;
size_t count;
ncclDataType_t datatype;
int peer;
ncclComm_t comm;
hipStream_t stream;
} ncclSend;
struct
{
void* recvbuff;
size_t count;
ncclDataType_t datatype;
int peer;
ncclComm_t comm;
hipStream_t stream;
} ncclRecv;
struct
{
ncclRedOp_t* op;
void* scalar;
ncclDataType_t datatype;
ncclScalarResidence_t residence;
ncclComm_t comm;
} ncclRedOpCreatePreMulSum;
struct
{
ncclRedOp_t op;
ncclComm_t comm;
} ncclRedOpDestroy;
struct
{
rocprofiler_rccl_api_no_args no_args;
} ncclGroupStart;
struct
{
rocprofiler_rccl_api_no_args no_args;
} ncclGroupEnd;
struct
{
int* version;
} ncclGetVersion;
struct
{
ncclUniqueId* out;
} ncclGetUniqueId;
struct
{
ncclComm_t* newcomm;
int nranks;
ncclUniqueId commId;
int myrank;
} ncclCommInitRank;
struct
{
ncclComm_t* comms;
int ndev;
const int* devlist;
} ncclCommInitAll;
struct
{
ncclComm_t* comm;
int nranks;
ncclUniqueId commId;
int myrank;
ncclConfig_t* config;
} ncclCommInitRankConfig;
struct
{
ncclComm_t comm;
} ncclCommFinalize;
struct
{
ncclComm_t comm;
} ncclCommDestroy;
struct
{
ncclComm_t comm;
} ncclCommAbort;
struct
{
ncclComm_t comm;
int color;
int key;
ncclComm_t* newcomm;
ncclConfig_t* config;
} ncclCommSplit;
struct
{
ncclResult_t code;
} ncclGetErrorString;
struct
{
ncclComm_t comm;
} ncclGetLastError;
struct
{
ncclComm_t comm;
ncclResult_t* asyncError;
} ncclCommGetAsyncError;
struct
{
ncclComm_t comm;
int* count;
} ncclCommCount;
struct
{
ncclComm_t comm;
int* devid;
} ncclCommCuDevice;
struct
{
ncclComm_t comm;
int* rank;
} ncclCommUserRank;
struct
{
void** ptr;
size_t size;
} ncclMemAlloc;
struct
{
void* ptr;
} ncclMemFree;
struct
{
const char* mscclAlgoFilePath;
mscclAlgoHandle_t* mscclAlgoHandle;
int rank;
} mscclLoadAlgo;
struct
{
const void* sendBuff;
const size_t* sendCounts;
const size_t* sDisPls;
void* recvBuff;
const size_t* recvCounts;
const size_t* rDisPls;
size_t count;
ncclDataType_t dataType;
int root;
int peer;
ncclRedOp_t op;
mscclAlgoHandle_t mscclAlgoHandle;
ncclComm_t comm;
hipStream_t stream;
} mscclRunAlgo;
struct
{
mscclAlgoHandle_t mscclAlgoHandle;
} mscclUnloadAlgo;
struct
{
ncclComm_t comm;
void* buff;
size_t size;
void** handle;
} ncclCommRegister;
struct
{
ncclComm_t comm;
void* handle;
} ncclCommDeregister;
} rocprofiler_rccl_api_args_t;
ROCPROFILER_EXTERN_C_FINI
+75
Dosyayı Görüntüle
@@ -0,0 +1,75 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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-sdk/version.h>
/**
* @brief ROCProfiler enumeration of HSA Core API tracing operations
*/
typedef enum // NOLINT(performance-enum-size)
{
ROCPROFILER_RCCL_API_ID_NONE = -1,
ROCPROFILER_RCCL_API_ID_ncclAllGather = 0,
ROCPROFILER_RCCL_API_ID_ncclAllReduce,
ROCPROFILER_RCCL_API_ID_ncclAllToAll,
ROCPROFILER_RCCL_API_ID_ncclAllToAllv,
ROCPROFILER_RCCL_API_ID_ncclBroadcast,
ROCPROFILER_RCCL_API_ID_ncclGather,
ROCPROFILER_RCCL_API_ID_ncclReduce,
ROCPROFILER_RCCL_API_ID_ncclReduceScatter,
ROCPROFILER_RCCL_API_ID_ncclScatter,
ROCPROFILER_RCCL_API_ID_ncclSend,
ROCPROFILER_RCCL_API_ID_ncclRecv,
ROCPROFILER_RCCL_API_ID_ncclRedOpCreatePreMulSum,
ROCPROFILER_RCCL_API_ID_ncclRedOpDestroy,
ROCPROFILER_RCCL_API_ID_ncclGroupStart,
ROCPROFILER_RCCL_API_ID_ncclGroupEnd,
ROCPROFILER_RCCL_API_ID_ncclGetVersion,
ROCPROFILER_RCCL_API_ID_ncclGetUniqueId,
ROCPROFILER_RCCL_API_ID_ncclCommInitRank,
ROCPROFILER_RCCL_API_ID_ncclCommInitAll,
ROCPROFILER_RCCL_API_ID_ncclCommInitRankConfig,
ROCPROFILER_RCCL_API_ID_ncclCommFinalize,
ROCPROFILER_RCCL_API_ID_ncclCommDestroy,
ROCPROFILER_RCCL_API_ID_ncclCommAbort,
ROCPROFILER_RCCL_API_ID_ncclCommSplit,
ROCPROFILER_RCCL_API_ID_ncclGetErrorString,
ROCPROFILER_RCCL_API_ID_ncclGetLastError,
ROCPROFILER_RCCL_API_ID_ncclCommGetAsyncError,
ROCPROFILER_RCCL_API_ID_ncclCommCount,
ROCPROFILER_RCCL_API_ID_ncclCommCuDevice,
ROCPROFILER_RCCL_API_ID_ncclCommUserRank,
ROCPROFILER_RCCL_API_ID_ncclMemAlloc,
ROCPROFILER_RCCL_API_ID_ncclMemFree,
ROCPROFILER_RCCL_API_ID_mscclLoadAlgo,
ROCPROFILER_RCCL_API_ID_mscclRunAlgo,
ROCPROFILER_RCCL_API_ID_mscclUnloadAlgo,
ROCPROFILER_RCCL_API_ID_ncclCommRegister,
ROCPROFILER_RCCL_API_ID_ncclCommDeregister,
ROCPROFILER_RCCL_API_ID_LAST,
} rocprofiler_rccl_api_id_t;
+31
Dosyayı Görüntüle
@@ -0,0 +1,31 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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
// NOLINTNEXTLINE(performance-enum-size)
typedef enum
{
ROCPROFILER_RCCL_TABLE_ID_NONE = -1,
ROCPROFILER_RCCL_TABLE_ID = 0,
ROCPROFILER_RCCL_TABLE_ID_LAST,
} rocprofiler_rccl_table_id_t;
+1
Dosyayı Görüntüle
@@ -92,6 +92,7 @@ struct config
bool counter_collection = get_env("ROCPROF_COUNTER_COLLECTION", false);
bool hip_runtime_api_trace = get_env("ROCPROF_HIP_RUNTIME_API_TRACE", false);
bool hip_compiler_api_trace = get_env("ROCPROF_HIP_COMPILER_API_TRACE", false);
bool rccl_api_trace = get_env("ROCPROF_RCCL_API_TRACE", false);
bool list_metrics = get_env("ROCPROF_LIST_METRICS", false);
bool list_metrics_output_file = get_env("ROCPROF_OUTPUT_LIST_METRICS_FILE", false);
bool stats = get_env("ROCPROF_STATS", false);
+1
Dosyayı Görüntüle
@@ -44,6 +44,7 @@ DEFINE_BUFFER_TYPE_NAME(KERNEL_DISPATCH, "KERNEL_DISPATCH", "kernel_dispatch")
DEFINE_BUFFER_TYPE_NAME(MEMORY_COPY, "MEMORY_COPY", "memory_copy")
DEFINE_BUFFER_TYPE_NAME(SCRATCH_MEMORY, "SCRATCH_MEMORY", "scratch_memory")
DEFINE_BUFFER_TYPE_NAME(COUNTER_COLLECTION, "COUNTER_COLLECTION", "counter_collection")
DEFINE_BUFFER_TYPE_NAME(RCCL, "RCCL_API", "rccl_api")
#undef DEFINE_BUFFER_TYPE_NAME
+1
Dosyayı Görüntüle
@@ -33,6 +33,7 @@ enum class domain_type
MEMORY_COPY,
SCRATCH_MEMORY,
COUNTER_COLLECTION,
RCCL,
LAST,
};
+37
Dosyayı Görüntüle
@@ -575,6 +575,43 @@ generate_csv(tool_table*
}
}
void
generate_csv(tool_table* tool_functions,
const std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>& data,
const stats_entry_t& stats)
{
if(data.empty()) return;
if(tool::get_config().stats && stats)
write_stats(get_stats_output_file("rccl_api_stats"), stats.entries);
auto ofs = tool::output_file{"rccl_api_trace",
tool::csv::api_csv_encoder{},
{"Domain",
"Function",
"Process_Id",
"Thread_Id",
"Correlation_Id",
"Start_Timestamp",
"End_Timestamp"}};
for(const auto& record : data)
{
auto row_ss = std::stringstream{};
auto api_name = tool_functions->tool_get_operation_name_fn(record.kind, record.operation);
rocprofiler::tool::csv::api_csv_encoder::write_row(
row_ss,
tool_functions->tool_get_domain_name_fn(record.kind),
api_name,
getpid(),
record.thread_id,
record.correlation_id.internal,
record.start_timestamp,
record.end_timestamp);
ofs << row_ss.str();
}
}
void
generate_csv(tool_table* /*tool_functions*/, const domain_stats_vec_t& data_v)
{
+6
Dosyayı Görüntüle
@@ -24,6 +24,7 @@
#include "generateStats.hpp"
#include "helper.hpp"
#include "rocprofiler-sdk/buffer_tracing.h"
#include "statistics.hpp"
#include <rocprofiler-sdk/agent.h>
@@ -70,6 +71,11 @@ generate_csv(tool_table*
const std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>& data,
const stats_entry_t& stats);
void
generate_csv(tool_table* tool_functions,
const std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>& data,
const stats_entry_t& stats);
void
generate_csv(tool_table* tool_functions, const domain_stats_vec_t& data);
} // namespace tool
+3 -1
Dosyayı Görüntüle
@@ -50,7 +50,8 @@ write_json(tool_table* tool
std::deque<rocprofiler_buffer_tracing_memory_copy_record_t>* memory_copy_deque,
std::deque<rocprofiler_tool_counter_collection_record_t>* counter_collection_deque,
std::deque<rocprofiler_buffer_tracing_marker_api_record_t>* marker_api_deque,
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_deque)
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_deque,
std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>* rccl_api_deque)
{
using JSONOutputArchive = cereal::MinimalJSONOutputArchive;
@@ -171,6 +172,7 @@ write_json(tool_table* tool
json_ar(cereal::make_nvp("hip_api", *hip_api_deque));
json_ar(cereal::make_nvp("hsa_api", *hsa_api_deque));
json_ar(cereal::make_nvp("marker_api", *marker_api_deque));
json_ar(cereal::make_nvp("rccl_api", *rccl_api_deque));
json_ar(cereal::make_nvp("memory_copy", *memory_copy_deque));
json_ar(cereal::make_nvp("scratch_memory", *scratch_memory_deque));
json_ar.finishNode();
+2 -1
Dosyayı Görüntüle
@@ -41,7 +41,8 @@ write_json(tool_table* tool
std::deque<rocprofiler_buffer_tracing_memory_copy_record_t>* memory_copy_deque,
std::deque<rocprofiler_tool_counter_collection_record_t>* counter_collection_deque,
std::deque<rocprofiler_buffer_tracing_marker_api_record_t>* marker_api_deque,
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_deque);
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_deque,
std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>* rccl_api_deque);
} // namespace tool
} // namespace rocprofiler
+5 -1
Dosyayı Görüntüle
@@ -352,7 +352,8 @@ write_otf2(tool_table* tool
std::deque<rocprofiler_buffer_tracing_kernel_dispatch_record_t>* kernel_dispatch_data,
std::deque<rocprofiler_buffer_tracing_memory_copy_record_t>* memory_copy_data,
std::deque<rocprofiler_buffer_tracing_marker_api_record_t>* marker_api_data,
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* /*scratch_memory_data*/)
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* /*scratch_memory_data*/,
std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>* rccl_api_data)
{
namespace sdk = ::rocprofiler::sdk;
@@ -399,6 +400,8 @@ write_otf2(tool_table* tool
tids.emplace(itr.thread_id);
for(auto itr : *marker_api_data)
tids.emplace(itr.thread_id);
for(auto itr : *rccl_api_data)
tids.emplace(itr.thread_id);
for(auto itr : *memory_copy_data)
{
@@ -555,6 +558,7 @@ write_otf2(tool_table* tool
add_event_data(hsa_api_data, sdk::category::hsa_api{});
add_event_data(hip_api_data, sdk::category::hip_api{});
add_event_data(marker_api_data, sdk::category::marker_api{});
add_event_data(rccl_api_data, sdk::category::rccl_api{});
}
for(auto itr : *memory_copy_data)
+2 -1
Dosyayı Görüntüle
@@ -39,6 +39,7 @@ write_otf2(tool_table* tool
std::deque<rocprofiler_buffer_tracing_kernel_dispatch_record_t>* kernel_dispatch_data,
std::deque<rocprofiler_buffer_tracing_memory_copy_record_t>* memory_copy_data,
std::deque<rocprofiler_buffer_tracing_marker_api_record_t>* marker_api_data,
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_data);
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_data,
std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>* rccl_api_data);
} // namespace tool
} // namespace rocprofiler
+33 -1
Dosyayı Görüntüle
@@ -71,7 +71,8 @@ write_perfetto(
std::deque<rocprofiler_buffer_tracing_kernel_dispatch_record_t>* kernel_dispatch_data,
std::deque<rocprofiler_buffer_tracing_memory_copy_record_t>* memory_copy_data,
std::deque<rocprofiler_buffer_tracing_marker_api_record_t>* marker_api_data,
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* /*scratch_memory_data*/)
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* /*scratch_memory_data*/,
std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>* rccl_api_data)
{
namespace sdk = ::rocprofiler::sdk;
@@ -155,6 +156,8 @@ write_perfetto(
tids.emplace(itr.thread_id);
for(auto itr : *marker_api_data)
tids.emplace(itr.thread_id);
for(auto itr : *rccl_api_data)
tids.emplace(itr.thread_id);
for(auto itr : *memory_copy_data)
{
@@ -342,6 +345,35 @@ write_perfetto(
tracing_session->FlushBlocking();
}
for(auto itr : *rccl_api_data)
{
auto name = buffer_names.at(itr.kind, itr.operation);
auto& track = thread_tracks.at(itr.thread_id);
TRACE_EVENT_BEGIN(sdk::perfetto_category<sdk::category::rccl_api>::name,
::perfetto::StaticString(name.data()),
track,
itr.start_timestamp,
::perfetto::Flow::ProcessScoped(itr.correlation_id.internal),
"begin_ns",
itr.start_timestamp,
"end_ns",
itr.end_timestamp,
"delta_ns",
(itr.end_timestamp - itr.start_timestamp),
"tid",
itr.thread_id,
"kind",
itr.kind,
"operation",
itr.operation,
"corr_id",
itr.correlation_id.internal);
TRACE_EVENT_END(
sdk::perfetto_category<sdk::category::rccl_api>::name, track, itr.end_timestamp);
tracing_session->FlushBlocking();
}
for(auto itr : *memory_copy_data)
{
auto name = buffer_names.at(itr.kind, itr.operation);
+2 -1
Dosyayı Görüntüle
@@ -40,6 +40,7 @@ write_perfetto(
std::deque<rocprofiler_buffer_tracing_kernel_dispatch_record_t>* kernel_dispatch_data,
std::deque<rocprofiler_buffer_tracing_memory_copy_record_t>* memory_copy_data,
std::deque<rocprofiler_buffer_tracing_marker_api_record_t>* marker_api_data,
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_data);
std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>* scratch_memory_data,
std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>* rccl_api_data);
} // namespace tool
} // namespace rocprofiler
+19 -3
Dosyayı Görüntüle
@@ -22,16 +22,18 @@
#include "generateStats.hpp"
#include "config.hpp"
#include "domain_type.hpp"
#include "helper.hpp"
#include "lib/common/logging.hpp"
#include "lib/rocprofiler-sdk-tool/domain_type.hpp"
#include "output_file.hpp"
#include "statistics.hpp"
#include <fmt/format.h>
#include "lib/common/logging.hpp"
#include <rocprofiler-sdk/fwd.h>
#include <rocprofiler-sdk/marker/api_id.h>
#include <fmt/format.h>
#include <unistd.h>
#include <cstdint>
#include <iomanip>
@@ -166,6 +168,20 @@ generate_stats(tool_table*
return get_stats(scratch_memory_stats);
}
stats_entry_t
generate_stats(tool_table* tool_functions,
const std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>& data)
{
auto rccl_stats = stats_map_t{};
for(const auto& record : data)
{
auto api_name = tool_functions->tool_get_operation_name_fn(record.kind, record.operation);
rccl_stats[api_name] += (record.end_timestamp - record.start_timestamp);
}
return get_stats(rccl_stats);
}
namespace
{
void
+4
Dosyayı Görüntüle
@@ -57,6 +57,10 @@ stats_entry_t
generate_stats(tool_table* tool_functions,
const std::deque<rocprofiler_buffer_tracing_scratch_memory_record_t>& data);
stats_entry_t
generate_stats(tool_table* tool_functions,
const std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>& data);
void
generate_stats(tool_table* tool_functions, const domain_stats_vec_t& data);
} // namespace tool
+3
Dosyayı Görüntüle
@@ -324,6 +324,9 @@ using memory_copy_buffered_output_t =
using marker_buffered_output_t =
::rocprofiler::tool::buffered_output<rocprofiler_buffer_tracing_marker_api_record_t,
domain_type::MARKER>;
using rccl_buffered_output_t =
::rocprofiler::tool::buffered_output<rocprofiler_buffer_tracing_rccl_api_record_t,
domain_type::RCCL>;
using counter_collection_buffered_output_t =
::rocprofiler::tool::buffered_output<rocprofiler_tool_counter_collection_record_t,
domain_type::COUNTER_COLLECTION>;
+43 -5
Dosyayı Görüntüle
@@ -44,6 +44,7 @@
#include "lib/common/utility.hpp"
#include <rocprofiler-sdk/agent.h>
#include <rocprofiler-sdk/buffer_tracing.h>
#include <rocprofiler-sdk/callback_tracing.h>
#include <rocprofiler-sdk/external_correlation.h>
#include <rocprofiler-sdk/fwd.h>
@@ -150,15 +151,17 @@ struct buffer_ids
rocprofiler_buffer_id_t memory_copy_trace = {};
rocprofiler_buffer_id_t counter_collection = {};
rocprofiler_buffer_id_t scratch_memory = {};
rocprofiler_buffer_id_t rccl_api_trace = {};
auto as_array() const
{
return std::array<rocprofiler_buffer_id_t, 6>{hsa_api_trace,
return std::array<rocprofiler_buffer_id_t, 7>{hsa_api_trace,
hip_api_trace,
kernel_trace,
memory_copy_trace,
counter_collection,
scratch_memory};
scratch_memory,
rccl_api_trace};
}
};
@@ -710,6 +713,13 @@ buffered_tracing_callback(rocprofiler_context_id_t /*context*/,
write_ring_buffer(*record, domain_type::HIP);
}
else if(header->kind == ROCPROFILER_BUFFER_TRACING_RCCL_API)
{
auto* record =
static_cast<rocprofiler_buffer_tracing_rccl_api_record_t*>(header->payload);
write_ring_buffer(*record, domain_type::RCCL);
}
else
{
ROCP_FATAL << fmt::format(
@@ -1423,6 +1433,28 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
}
}
if(tool::get_config().rccl_api_trace)
{
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
buffer_size,
buffer_watermark,
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
buffered_tracing_callback,
tool_data,
&get_buffers().rccl_api_trace),
"buffer creation");
auto _status =
rocprofiler_configure_buffer_tracing_service(get_client_ctx(),
ROCPROFILER_BUFFER_TRACING_RCCL_API,
nullptr,
0,
get_buffers().rccl_api_trace);
if(_status != ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED)
ROCPROFILER_CALL(_status, "buffer tracing service for rccl api configure");
}
if(tool::get_config().counter_collection)
{
ROCPROFILER_CALL(
@@ -1557,6 +1589,7 @@ tool_fini(void* /*tool_data*/)
counter_collection_buffered_output_t{tool::get_config().counter_collection};
auto scratch_memory_output =
scratch_memory_buffered_output_t{tool::get_config().scratch_memory_trace};
auto rccl_output = rccl_buffered_output_t{tool::get_config().rccl_api_trace};
auto node_id_sort = [](const auto& lhs, const auto& rhs) { return lhs.node_id < rhs.node_id; };
@@ -1579,6 +1612,7 @@ tool_fini(void* /*tool_data*/)
generate_output(hip_output, contributions);
generate_output(memory_copy_output, contributions);
generate_output(marker_output, contributions);
generate_output(rccl_output, contributions);
generate_output(counters_output, contributions);
generate_output(scratch_memory_output, contributions);
@@ -1601,7 +1635,8 @@ tool_fini(void* /*tool_data*/)
&memory_copy_output.element_data,
&counters_output.element_data,
&marker_output.element_data,
&scratch_memory_output.element_data);
&scratch_memory_output.element_data,
&rccl_output.element_data);
}
if(tool::get_config().pftrace_output)
@@ -1614,7 +1649,8 @@ tool_fini(void* /*tool_data*/)
&kernel_dispatch_output.element_data,
&memory_copy_output.element_data,
&marker_output.element_data,
&scratch_memory_output.element_data);
&scratch_memory_output.element_data,
&rccl_output.element_data);
}
if(tool::get_config().otf2_output)
@@ -1627,7 +1663,8 @@ tool_fini(void* /*tool_data*/)
&kernel_dispatch_output.element_data,
&memory_copy_output.element_data,
&marker_output.element_data,
&scratch_memory_output.element_data);
&scratch_memory_output.element_data,
&rccl_output.element_data);
}
if(tool::get_config().summary_output)
@@ -1644,6 +1681,7 @@ tool_fini(void* /*tool_data*/)
destroy_output(marker_output);
destroy_output(counters_output);
destroy_output(scratch_memory_output);
destroy_output(rccl_output);
fini_tool_table();
if(destructors)
+2
Dosyayı Görüntüle
@@ -47,12 +47,14 @@ add_subdirectory(thread_trace)
add_subdirectory(tracing)
add_subdirectory(kernel_dispatch)
add_subdirectory(page_migration)
add_subdirectory(rccl)
add_subdirectory(details)
target_link_libraries(
rocprofiler-object-library
PUBLIC rocprofiler-sdk::rocprofiler-headers rocprofiler-sdk::rocprofiler-hip-nolink
rocprofiler-sdk::rocprofiler-hsa-runtime-nolink
rocprofiler-sdk::rocprofiler-rccl-nolink
PRIVATE rocprofiler-sdk::rocprofiler-build-flags
rocprofiler-sdk::rocprofiler-memcheck
rocprofiler-sdk::rocprofiler-common-library
+28 -1
Dosyayı Görüntüle
@@ -24,6 +24,7 @@
#include <rocprofiler-sdk/hip/table_id.h>
#include <rocprofiler-sdk/hsa/table_id.h>
#include <rocprofiler-sdk/marker/table_id.h>
#include <rocprofiler-sdk/rccl/table_id.h>
#include <rocprofiler-sdk/rocprofiler.h>
#include "lib/common/logging.hpp"
@@ -36,6 +37,7 @@
#include "lib/rocprofiler-sdk/kernel_dispatch/kernel_dispatch.hpp"
#include "lib/rocprofiler-sdk/marker/marker.hpp"
#include "lib/rocprofiler-sdk/page_migration/page_migration.hpp"
#include "lib/rocprofiler-sdk/rccl/rccl.hpp"
#include "lib/rocprofiler-sdk/registration.hpp"
#include <atomic>
@@ -82,6 +84,7 @@ ROCPROFILER_BUFFER_TRACING_KIND_STRING(KERNEL_DISPATCH)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(PAGE_MIGRATION)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(SCRATCH_MEMORY)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(CORRELATION_ID_RETIREMENT)
ROCPROFILER_BUFFER_TRACING_KIND_STRING(RCCL_API)
template <size_t Idx, size_t... Tail>
std::pair<const char*, size_t>
@@ -92,6 +95,19 @@ get_kind_name(rocprofiler_buffer_tracing_kind_t kind, std::index_sequence<Idx, T
if constexpr(sizeof...(Tail) > 0) return get_kind_name(kind, std::index_sequence<Tail...>{});
return {nullptr, 0};
}
auto
get_unsupported()
{
auto unsupported = std::unordered_set<rocprofiler_buffer_tracing_kind_t>{};
#if ROCPROFILER_SDK_RCCL_HAS_API_TRACE == 0
// Built against RCCL which does not support API tracing
unsupported.emplace(ROCPROFILER_BUFFER_TRACING_RCCL_API);
#endif
return unsupported;
}
} // namespace
} // namespace buffer_tracing
} // namespace rocprofiler
@@ -104,10 +120,11 @@ rocprofiler_configure_buffer_tracing_service(rocprofiler_context_id_t
size_t operations_count,
rocprofiler_buffer_id_t buffer_id)
{
static auto unsupported = ::rocprofiler::buffer_tracing::get_unsupported();
if(rocprofiler::registration::get_init_status() > -1)
return ROCPROFILER_STATUS_ERROR_CONFIGURATION_LOCKED;
static auto unsupported = std::unordered_set<rocprofiler_buffer_tracing_kind_t>{};
if(unsupported.count(kind) > 0) return ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED;
auto* ctx = rocprofiler::context::get_mutable_registered_context(context_id);
@@ -221,6 +238,11 @@ rocprofiler_query_buffer_tracing_kind_operation_name(rocprofiler_buffer_tracing_
val = rocprofiler::marker::name_by_id<ROCPROFILER_MARKER_TABLE_ID_RoctxName>(operation);
break;
}
case ROCPROFILER_BUFFER_TRACING_RCCL_API:
{
val = rocprofiler::rccl::name_by_id<ROCPROFILER_RCCL_TABLE_ID>(operation);
break;
}
case ROCPROFILER_BUFFER_TRACING_HIP_RUNTIME_API:
{
val = rocprofiler::hip::name_by_id<ROCPROFILER_HIP_TABLE_ID_Runtime>(operation);
@@ -332,6 +354,11 @@ rocprofiler_iterate_buffer_tracing_kind_operations(
ops = rocprofiler::marker::get_ids<ROCPROFILER_MARKER_TABLE_ID_RoctxName>();
break;
}
case ROCPROFILER_BUFFER_TRACING_RCCL_API:
{
ops = rocprofiler::rccl::get_ids<ROCPROFILER_RCCL_TABLE_ID>();
break;
}
case ROCPROFILER_BUFFER_TRACING_HIP_RUNTIME_API:
{
ops = rocprofiler::hip::get_ids<ROCPROFILER_HIP_TABLE_ID_Runtime>();
+31
Dosyayı Görüntüle
@@ -25,6 +25,7 @@
#include <rocprofiler-sdk/hip/table_id.h>
#include <rocprofiler-sdk/hsa/table_id.h>
#include <rocprofiler-sdk/marker/table_id.h>
#include <rocprofiler-sdk/rccl/table_id.h>
#include <rocprofiler-sdk/rocprofiler.h>
#include "lib/rocprofiler-sdk/code_object/code_object.hpp"
@@ -36,6 +37,7 @@
#include "lib/rocprofiler-sdk/hsa/scratch_memory.hpp"
#include "lib/rocprofiler-sdk/kernel_dispatch/kernel_dispatch.hpp"
#include "lib/rocprofiler-sdk/marker/marker.hpp"
#include "lib/rocprofiler-sdk/rccl/rccl.hpp"
#include "lib/rocprofiler-sdk/registration.hpp"
#include <atomic>
@@ -79,6 +81,7 @@ ROCPROFILER_CALLBACK_TRACING_KIND_STRING(CODE_OBJECT)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(SCRATCH_MEMORY)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(KERNEL_DISPATCH)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(MEMORY_COPY)
ROCPROFILER_CALLBACK_TRACING_KIND_STRING(RCCL_API)
template <size_t Idx, size_t... Tail>
std::pair<const char*, size_t>
@@ -89,6 +92,19 @@ get_kind_name(rocprofiler_callback_tracing_kind_t kind, std::index_sequence<Idx,
if constexpr(sizeof...(Tail) > 0) return get_kind_name(kind, std::index_sequence<Tail...>{});
return {nullptr, 0};
}
auto
get_unsupported()
{
auto unsupported = std::unordered_set<rocprofiler_callback_tracing_kind_t>{};
#if ROCPROFILER_SDK_RCCL_HAS_API_TRACE == 0
// Built against RCCL which does not support API tracing
unsupported.emplace(ROCPROFILER_CALLBACK_TRACING_RCCL_API);
#endif
return unsupported;
}
} // namespace
} // namespace callback_tracing
} // namespace rocprofiler
@@ -102,9 +118,13 @@ rocprofiler_configure_callback_tracing_service(rocprofiler_context_id_t
rocprofiler_callback_tracing_cb_t callback,
void* callback_args)
{
static auto unsupported = ::rocprofiler::callback_tracing::get_unsupported();
if(rocprofiler::registration::get_init_status() > -1)
return ROCPROFILER_STATUS_ERROR_CONFIGURATION_LOCKED;
if(unsupported.count(kind) > 0) return ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED;
auto* ctx = rocprofiler::context::get_mutable_registered_context(context_id);
if(!ctx) return ROCPROFILER_STATUS_ERROR_CONTEXT_NOT_FOUND;
@@ -200,6 +220,11 @@ rocprofiler_query_callback_tracing_kind_operation_name(rocprofiler_callback_trac
val = rocprofiler::marker::name_by_id<ROCPROFILER_MARKER_TABLE_ID_RoctxName>(operation);
break;
}
case ROCPROFILER_CALLBACK_TRACING_RCCL_API:
{
val = rocprofiler::rccl::name_by_id<ROCPROFILER_RCCL_TABLE_ID>(operation);
break;
}
case ROCPROFILER_CALLBACK_TRACING_HIP_RUNTIME_API:
{
val = rocprofiler::hip::name_by_id<ROCPROFILER_HIP_TABLE_ID_Runtime>(operation);
@@ -309,6 +334,11 @@ rocprofiler_iterate_callback_tracing_kind_operations(
ops = rocprofiler::marker::get_ids<ROCPROFILER_MARKER_TABLE_ID_RoctxName>();
break;
}
case ROCPROFILER_CALLBACK_TRACING_RCCL_API:
{
ops = rocprofiler::rccl::get_ids<ROCPROFILER_RCCL_TABLE_ID>();
break;
}
case ROCPROFILER_CALLBACK_TRACING_HIP_RUNTIME_API:
{
ops = rocprofiler::hip::get_ids<ROCPROFILER_HIP_TABLE_ID_Runtime>();
@@ -463,6 +493,7 @@ rocprofiler_iterate_callback_tracing_kind_operation_args(
case ROCPROFILER_CALLBACK_TRACING_CODE_OBJECT:
case ROCPROFILER_CALLBACK_TRACING_KERNEL_DISPATCH:
case ROCPROFILER_CALLBACK_TRACING_MEMORY_COPY:
case ROCPROFILER_CALLBACK_TRACING_RCCL_API:
{
return ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED;
}
+8 -1
Dosyayı Görüntüle
@@ -33,6 +33,7 @@
#include <hsa/hsa_api_trace.h>
#include <hip/amd_detail/hip_api_trace.hpp>
#include "lib/rocprofiler-sdk/rccl/rccl.hpp"
#include <cstdint>
#include <mutex>
@@ -55,7 +56,8 @@ constexpr auto intercept_library_seq = library_sequence_t<ROCPROFILER_HSA_TABLE,
ROCPROFILER_HIP_COMPILER_TABLE,
ROCPROFILER_MARKER_CORE_TABLE,
ROCPROFILER_MARKER_CONTROL_TABLE,
ROCPROFILER_MARKER_NAME_TABLE>{};
ROCPROFILER_MARKER_NAME_TABLE,
ROCPROFILER_RCCL_TABLE>{};
// check that intercept_library_seq is up to date
static_assert((1 << (intercept_library_seq.size() - 1)) == ROCPROFILER_TABLE_LAST,
@@ -185,6 +187,11 @@ template void notify_intercept_table_registration(rocprofiler_intercept_table_t,
uint64_t,
uint64_t,
std::tuple<HipCompilerDispatchTable*>);
template void notify_intercept_table_registration(rocprofiler_intercept_table_t,
uint64_t,
uint64_t,
std::tuple<rcclApiFuncTable*>);
} // namespace intercept_table
} // namespace rocprofiler
+2 -1
Dosyayı Görüntüle
@@ -121,7 +121,8 @@ using creation_notifier_cb_t = void (*)(rocprofiler_runtime_library_t, void*);
constexpr auto creation_notifier_library_seq = library_sequence_t<ROCPROFILER_LIBRARY,
ROCPROFILER_HSA_LIBRARY,
ROCPROFILER_HIP_LIBRARY,
ROCPROFILER_MARKER_LIBRARY>{};
ROCPROFILER_MARKER_LIBRARY,
ROCPROFILER_RCCL_LIBRARY>{};
// check that creation_notifier_library_seq is up to date
static_assert((1 << (creation_notifier_library_seq.size() - 1)) == ROCPROFILER_LIBRARY_LAST,
+7
Dosyayı Görüntüle
@@ -0,0 +1,7 @@
set(ROCPROFILER_LIB_RCCL_SOURCES abi.cpp rccl.cpp)
set(ROCPROFILER_LIB_RCCL_HEADERS defines.hpp rccl.hpp)
target_sources(rocprofiler-object-library PRIVATE ${ROCPROFILER_LIB_RCCL_SOURCES}
${ROCPROFILER_LIB_RCCL_HEADERS})
add_subdirectory(details)
+82
Dosyayı Görüntüle
@@ -0,0 +1,82 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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.
#include "lib/rocprofiler-sdk/rccl/rccl.hpp"
#if ROCPROFILER_SDK_RCCL_HAS_API_TRACE > 0
# include "lib/common/abi.hpp"
# include "lib/common/defines.hpp"
# include <rocprofiler-sdk/rccl.h>
# include <rocprofiler-sdk/version.h>
namespace rocprofiler
{
namespace rccl
{
static_assert(RCCL_API_TRACE_VERSION_MAJOR == 0, "Major version updated for RCCL dispatch table");
static_assert(RCCL_API_TRACE_VERSION_PATCH == 0, "Patch version updated for RCCL dispatch table");
ROCP_SDK_ENFORCE_ABI_VERSIONING(rcclApiFuncTable, 37)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclAllGather_fn, 0)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclAllReduce_fn, 1)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclAllToAll_fn, 2)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclAllToAllv_fn, 3)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclBroadcast_fn, 4)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclGather_fn, 5)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclReduce_fn, 6)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclReduceScatter_fn, 7)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclScatter_fn, 8)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclSend_fn, 9)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclRecv_fn, 10)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclRedOpCreatePreMulSum_fn, 11)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclRedOpDestroy_fn, 12)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclGroupStart_fn, 13)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclGroupEnd_fn, 14)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclGetVersion_fn, 15)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclGetUniqueId_fn, 16)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommInitRank_fn, 17)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommInitAll_fn, 18)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommInitRankConfig_fn, 19)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommFinalize_fn, 20)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommDestroy_fn, 21)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommAbort_fn, 22)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommSplit_fn, 23)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclGetErrorString_fn, 24)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclGetLastError_fn, 25)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommGetAsyncError_fn, 26)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommCount_fn, 27)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommCuDevice_fn, 28)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommUserRank_fn, 29)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclMemAlloc_fn, 30)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclMemFree_fn, 31)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, mscclLoadAlgo_fn, 32)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, mscclRunAlgo_fn, 33)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, mscclUnloadAlgo_fn, 34)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommRegister_fn, 35)
ROCP_SDK_ENFORCE_ABI(rcclApiFuncTable, ncclCommDeregister_fn, 36)
} // namespace rccl
} // namespace rocprofiler
#endif
+212
Dosyayı Görüntüle
@@ -0,0 +1,212 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 "lib/common/defines.hpp"
#define RCCL_API_INFO_DEFINITION_0(RCCL_TABLE, RCCL_API_ID, RCCL_FUNC, RCCL_FUNC_PTR) \
namespace rocprofiler \
{ \
namespace rccl \
{ \
template <> \
struct rccl_api_info<RCCL_TABLE, RCCL_API_ID> : rccl_domain_info<RCCL_TABLE> \
{ \
static constexpr auto table_idx = RCCL_TABLE; \
static constexpr auto operation_idx = RCCL_API_ID; \
static constexpr auto name = #RCCL_FUNC; \
\
using domain_type = rccl_domain_info<table_idx>; \
using this_type = rccl_api_info<table_idx, operation_idx>; \
using base_type = rccl_api_impl<table_idx, operation_idx>; \
\
using domain_type::callback_domain_idx; \
using domain_type::buffered_domain_idx; \
using domain_type::args_type; \
using domain_type::retval_type; \
using domain_type::callback_data_type; \
\
static constexpr auto offset() \
{ \
return offsetof(rccl_table_lookup<table_idx>::type, RCCL_FUNC_PTR); \
} \
\
static_assert(offsetof(rccl_table_lookup<table_idx>::type, RCCL_FUNC_PTR) == \
(sizeof(size_t) + (operation_idx * sizeof(void*))), \
"ABI error for " #RCCL_FUNC); \
\
static auto& get_table() { return rccl_table_lookup<table_idx>{}(); } \
\
template <typename TableT> \
static auto& get_table(TableT& _v) \
{ \
return rccl_table_lookup<table_idx>{}(_v); \
} \
\
template <typename TableT> \
static auto& get_table_func(TableT& _table) \
{ \
if constexpr(std::is_pointer<TableT>::value) \
{ \
assert(_table != nullptr && "nullptr to MARKER table for " #RCCL_FUNC \
" function"); \
return _table->RCCL_FUNC_PTR; \
} \
else \
{ \
return _table.RCCL_FUNC_PTR; \
} \
} \
\
static auto& get_table_func() { return get_table_func(get_table()); } \
\
template <typename DataT> \
static auto& get_api_data_args(DataT& _data) \
{ \
return _data.RCCL_FUNC; \
} \
\
template <typename RetT, typename... Args> \
static auto get_functor(RetT (*)(Args...)) \
{ \
return &base_type::functor<RetT, Args...>; \
} \
\
static std::vector<void*> as_arg_addr(callback_data_type) { return std::vector<void*>{}; } \
\
static std::vector<common::stringified_argument> as_arg_list(callback_data_type, int32_t) \
{ \
return {}; \
} \
}; \
} \
}
#define RCCL_API_INFO_DEFINITION_V(RCCL_TABLE, RCCL_API_ID, RCCL_FUNC, RCCL_FUNC_PTR, ...) \
namespace rocprofiler \
{ \
namespace rccl \
{ \
template <> \
struct rccl_api_info<RCCL_TABLE, RCCL_API_ID> : rccl_domain_info<RCCL_TABLE> \
{ \
static constexpr auto table_idx = RCCL_TABLE; \
static constexpr auto operation_idx = RCCL_API_ID; \
static constexpr auto name = #RCCL_FUNC; \
\
using domain_type = rccl_domain_info<table_idx>; \
using this_type = rccl_api_info<table_idx, operation_idx>; \
using base_type = rccl_api_impl<table_idx, operation_idx>; \
\
static constexpr auto callback_domain_idx = domain_type::callback_domain_idx; \
static constexpr auto buffered_domain_idx = domain_type::buffered_domain_idx; \
\
using domain_type::args_type; \
using domain_type::retval_type; \
using domain_type::callback_data_type; \
\
static constexpr auto offset() \
{ \
return offsetof(rccl_table_lookup<table_idx>::type, RCCL_FUNC_PTR); \
} \
\
static_assert(offsetof(rccl_table_lookup<table_idx>::type, RCCL_FUNC_PTR) == \
(sizeof(size_t) + (operation_idx * sizeof(void*))), \
"ABI error for " #RCCL_FUNC); \
\
static auto& get_table() { return rccl_table_lookup<table_idx>{}(); } \
\
template <typename TableT> \
static auto& get_table(TableT& _v) \
{ \
return rccl_table_lookup<table_idx>{}(_v); \
} \
\
template <typename TableT> \
static auto& get_table_func(TableT& _table) \
{ \
if constexpr(std::is_pointer<TableT>::value) \
{ \
assert(_table != nullptr && "nullptr to MARKER table for " #RCCL_FUNC \
" function"); \
return _table->RCCL_FUNC_PTR; \
} \
else \
{ \
return _table.RCCL_FUNC_PTR; \
} \
} \
\
static auto& get_table_func() { return get_table_func(get_table()); } \
\
template <typename DataT> \
static auto& get_api_data_args(DataT& _data) \
{ \
return _data.RCCL_FUNC; \
} \
\
template <typename RetT, typename... Args> \
static auto get_functor(RetT (*)(Args...)) \
{ \
return &base_type::functor<RetT, Args...>; \
} \
\
static std::vector<void*> as_arg_addr(callback_data_type trace_data) \
{ \
return std::vector<void*>{ \
GET_ADDR_MEMBER_FIELDS(get_api_data_args(trace_data.args), __VA_ARGS__)}; \
} \
}; \
} \
}
#define RCCL_API_TABLE_LOOKUP_DEFINITION(TABLE_ID, TYPE) \
namespace rocprofiler \
{ \
namespace rccl \
{ \
namespace \
{ \
template <> \
auto* get_table<TABLE_ID>() \
{ \
return get_table_impl<TYPE>(); \
} \
} \
\
template <> \
struct rccl_table_lookup<TABLE_ID> \
{ \
using type = TYPE; \
auto& operator()(type& _v) const { return _v; } \
auto& operator()(type* _v) const { return *_v; } \
auto& operator()() const { return (*this)(get_table<TABLE_ID>()); } \
}; \
\
template <> \
struct rccl_table_id_lookup<TYPE> \
{ \
static constexpr auto value = TABLE_ID; \
}; \
} \
}
+8
Dosyayı Görüntüle
@@ -0,0 +1,8 @@
#
#
#
set(ROCPROFILER_LIB_RCCL_DETAILS_SOURCES)
set(ROCPROFILER_LIB_RCCL_DETAILS_HEADERS api_trace.h)
target_sources(rocprofiler-object-library PRIVATE ${ROCPROFILER_LIB_RCCL_DETAILS_SOURCES}
${ROCPROFILER_LIB_RCCL_DETAILS_HEADERS})
+254
Dosyayı Görüntüle
@@ -0,0 +1,254 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 <rccl/rccl.h>
#include <stddef.h>
#include <stdint.h>
// should only be increased if fundamental changes to dispatch table(s)
#define RCCL_API_TRACE_VERSION_MAJOR 0
// should be increased every time new members are added to existing dispatch tables
#define RCCL_API_TRACE_VERSION_PATCH 0
#if !defined(RCCL_EXTERN_C_INIT)
# ifdef __cplusplus
# define RCCL_EXTERN_C_INIT extern "C" {
# else
# define RCCL_EXTERN_C_INIT
# endif
#endif
#if !defined(RCCL_EXTERN_C_FINI)
# ifdef __cplusplus
# define RCCL_EXTERN_C_FINI }
# else
# define RCCL_EXTERN_C_FINI
# endif
#endif
RCCL_EXTERN_C_INIT
typedef uint64_t rccl_range_id_t;
typedef ncclResult_t (*ncclAllGather_fn_t)(const void* sendbuff,
void* recvbuff,
size_t sendcount,
ncclDataType_t datatype,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclAllReduce_fn_t)(const void* sendbuff,
void* recvbuff,
size_t count,
ncclDataType_t datatype,
ncclRedOp_t op,
struct ncclComm* comm,
hipStream_t stream);
typedef ncclResult_t (*ncclAllToAll_fn_t)(const void* sendbuff,
void* recvbuff,
size_t count,
ncclDataType_t datatype,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclAllToAllv_fn_t)(const void* sendbuff,
const size_t sendcounts[],
const size_t sdispls[],
void* recvbuff,
const size_t recvcounts[],
const size_t rdispls[],
ncclDataType_t datatype,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclBroadcast_fn_t)(const void* sendbuff,
void* recvbuff,
size_t count,
ncclDataType_t datatype,
int root,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclGather_fn_t)(const void* sendbuff,
void* recvbuff,
size_t sendcount,
ncclDataType_t datatype,
int root,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclReduce_fn_t)(const void* sendbuff,
void* recvbuff,
size_t count,
ncclDataType_t datatype,
ncclRedOp_t op,
int root,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclReduceScatter_fn_t)(const void* sendbuff,
void* recvbuff,
size_t recvcount,
ncclDataType_t datatype,
ncclRedOp_t op,
struct ncclComm* comm,
hipStream_t stream);
typedef ncclResult_t (*ncclScatter_fn_t)(const void* sendbuff,
void* recvbuff,
size_t recvcount,
ncclDataType_t datatype,
int root,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclSend_fn_t)(const void* sendbuff,
size_t count,
ncclDataType_t datatype,
int peer,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclRecv_fn_t)(void* recvbuff,
size_t count,
ncclDataType_t datatype,
int peer,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*ncclRedOpCreatePreMulSum_fn_t)(ncclRedOp_t* op,
void* scalar,
ncclDataType_t datatype,
ncclScalarResidence_t residence,
ncclComm_t comm);
typedef ncclResult_t (*ncclRedOpDestroy_fn_t)(ncclRedOp_t op, ncclComm_t comm);
typedef ncclResult_t (*ncclGroupStart_fn_t)();
typedef ncclResult_t (*ncclGroupEnd_fn_t)();
typedef ncclResult_t (*ncclGetVersion_fn_t)(int* version);
typedef ncclResult_t (*ncclGetUniqueId_fn_t)(ncclUniqueId* out);
typedef ncclResult_t (*ncclCommInitRank_fn_t)(ncclComm_t* newcomm,
int nranks,
ncclUniqueId commId,
int myrank);
typedef ncclResult_t (*ncclCommInitAll_fn_t)(ncclComm_t* comms, int ndev, const int* devlist);
typedef ncclResult_t (*ncclCommInitRankConfig_fn_t)(ncclComm_t* comm,
int nranks,
ncclUniqueId commId,
int myrank,
ncclConfig_t* config);
typedef ncclResult_t (*ncclCommFinalize_fn_t)(ncclComm_t comm);
typedef ncclResult_t (*ncclCommDestroy_fn_t)(ncclComm_t comm);
typedef ncclResult_t (*ncclCommAbort_fn_t)(ncclComm_t comm);
typedef ncclResult_t (*ncclCommSplit_fn_t)(ncclComm_t comm,
int color,
int key,
ncclComm_t* newcomm,
ncclConfig_t* config);
typedef const char* (*ncclGetErrorString_fn_t)(ncclResult_t code);
typedef const char* (*ncclGetLastError_fn_t)(const ncclComm_t comm);
typedef ncclResult_t (*ncclCommGetAsyncError_fn_t)(ncclComm_t comm, ncclResult_t* asyncError);
typedef ncclResult_t (*ncclCommCount_fn_t)(const ncclComm_t comm, int* count);
typedef ncclResult_t (*ncclCommCuDevice_fn_t)(const ncclComm_t comm, int* devid);
typedef ncclResult_t (*ncclCommUserRank_fn_t)(const ncclComm_t comm, int* rank);
typedef ncclResult_t (*ncclMemAlloc_fn_t)(void** ptr, size_t size);
typedef ncclResult_t (*ncclMemFree_fn_t)(void* ptr);
typedef ncclResult_t (*mscclLoadAlgo_fn_t)(const char* mscclAlgoFilePath,
mscclAlgoHandle_t* mscclAlgoHandle,
int rank);
typedef ncclResult_t (*mscclRunAlgo_fn_t)(const void* sendBuff,
const size_t sendCounts[],
const size_t sDisPls[],
void* recvBuff,
const size_t recvCounts[],
const size_t rDisPls[],
size_t count,
ncclDataType_t dataType,
int root,
int peer,
ncclRedOp_t op,
mscclAlgoHandle_t mscclAlgoHandle,
ncclComm_t comm,
hipStream_t stream);
typedef ncclResult_t (*mscclUnloadAlgo_fn_t)(mscclAlgoHandle_t mscclAlgoHandle);
typedef ncclResult_t (*ncclCommRegister_fn_t)(const ncclComm_t comm,
void* buff,
size_t size,
void** handle);
typedef ncclResult_t (*ncclCommDeregister_fn_t)(const ncclComm_t comm, void* handle);
typedef struct rcclApiFuncTable
{
uint64_t size;
ncclAllGather_fn_t ncclAllGather_fn;
ncclAllReduce_fn_t ncclAllReduce_fn;
ncclAllToAll_fn_t ncclAllToAll_fn;
ncclAllToAllv_fn_t ncclAllToAllv_fn;
ncclBroadcast_fn_t ncclBroadcast_fn;
ncclGather_fn_t ncclGather_fn;
ncclReduce_fn_t ncclReduce_fn;
ncclReduceScatter_fn_t ncclReduceScatter_fn;
ncclScatter_fn_t ncclScatter_fn;
ncclSend_fn_t ncclSend_fn;
ncclRecv_fn_t ncclRecv_fn;
ncclRedOpCreatePreMulSum_fn_t ncclRedOpCreatePreMulSum_fn;
ncclRedOpDestroy_fn_t ncclRedOpDestroy_fn;
ncclGroupStart_fn_t ncclGroupStart_fn;
ncclGroupEnd_fn_t ncclGroupEnd_fn;
ncclGetVersion_fn_t ncclGetVersion_fn;
ncclGetUniqueId_fn_t ncclGetUniqueId_fn;
ncclCommInitRank_fn_t ncclCommInitRank_fn;
ncclCommInitAll_fn_t ncclCommInitAll_fn;
ncclCommInitRankConfig_fn_t ncclCommInitRankConfig_fn;
ncclCommFinalize_fn_t ncclCommFinalize_fn;
ncclCommDestroy_fn_t ncclCommDestroy_fn;
ncclCommAbort_fn_t ncclCommAbort_fn;
ncclCommSplit_fn_t ncclCommSplit_fn;
ncclGetErrorString_fn_t ncclGetErrorString_fn;
ncclGetLastError_fn_t ncclGetLastError_fn;
ncclCommGetAsyncError_fn_t ncclCommGetAsyncError_fn;
ncclCommCount_fn_t ncclCommCount_fn;
ncclCommCuDevice_fn_t ncclCommCuDevice_fn;
ncclCommUserRank_fn_t ncclCommUserRank_fn;
ncclMemAlloc_fn_t ncclMemAlloc_fn;
ncclMemFree_fn_t ncclMemFree_fn;
mscclLoadAlgo_fn_t mscclLoadAlgo_fn;
mscclRunAlgo_fn_t mscclRunAlgo_fn;
mscclUnloadAlgo_fn_t mscclUnloadAlgo_fn;
ncclCommRegister_fn_t ncclCommRegister_fn;
ncclCommDeregister_fn_t ncclCommDeregister_fn;
} rcclApiFuncTable;
RCCL_EXTERN_C_FINI
+557
Dosyayı Görüntüle
@@ -0,0 +1,557 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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.
#include "lib/rocprofiler-sdk/rccl/rccl.hpp"
#include "lib/common/defines.hpp"
#include "lib/common/static_object.hpp"
#include "lib/common/utility.hpp"
#include "lib/rocprofiler-sdk/buffer.hpp"
#include "lib/rocprofiler-sdk/context/context.hpp"
#include "lib/rocprofiler-sdk/hip/hip.hpp"
#include "lib/rocprofiler-sdk/hip/utils.hpp"
#include "lib/rocprofiler-sdk/registration.hpp"
#include "lib/rocprofiler-sdk/tracing/tracing.hpp"
#include <rocprofiler-sdk/buffer.h>
#include <rocprofiler-sdk/callback_tracing.h>
#include <rocprofiler-sdk/fwd.h>
#include <rocprofiler-sdk/rccl/table_id.h>
#include <hip/driver_types.h>
#include <hip/hip_runtime_api.h>
// must be included after runtime api
#include <hip/hip_deprecated.h>
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <utility>
namespace rocprofiler
{
namespace rccl
{
namespace
{
struct null_type
{};
template <typename Tp>
auto
get_default_retval()
{
if constexpr(std::is_pointer<Tp>::value)
{
Tp v = nullptr;
return v;
}
else if constexpr(std::is_same<Tp, ncclResult_t>::value)
return ncclInternalError; // No unknown error, ok?
else if constexpr(std::is_same<Tp, const char*>::value)
return "UnknownString"; // ok?
else
static_assert(std::is_empty<Tp>::value, "Error! unsupported return type");
}
template <typename DataT, typename Tp>
void
set_data_retval(DataT& _data, Tp _val)
{
if constexpr(std::is_same<Tp, ncclResult_t>::value)
{
_data.ncclResult_t_retval = _val;
}
else if constexpr(std::is_same<Tp, const char*>::value)
{
_data.const_charp_retval = _val;
}
else
{
static_assert(std::is_empty<Tp>::value, "Error! unsupported return type");
}
}
template <typename Tp>
Tp*
get_table_impl()
{
static auto*& _v = common::static_object<Tp>::construct(common::init_public_api_struct(Tp{}));
return _v;
}
template <size_t TableIdx>
auto*
get_table();
} // namespace
template <size_t TableIdx, size_t OpIdx>
template <typename DataArgsT, typename... Args>
auto
rccl_api_impl<TableIdx, OpIdx>::set_data_args(DataArgsT& _data_args, Args... args)
{
if constexpr(sizeof...(Args) == 0)
_data_args.no_args.empty = '\0';
else
_data_args = DataArgsT{args...};
}
template <size_t TableIdx, size_t OpIdx>
template <typename FuncT, typename... Args>
auto
rccl_api_impl<TableIdx, OpIdx>::exec(FuncT&& _func, Args&&... args)
{
using return_type = std::decay_t<std::invoke_result_t<FuncT, Args...>>;
if(_func)
{
if constexpr(std::is_void<return_type>::value)
{
_func(std::forward<Args>(args)...);
return null_type{};
}
else
{
return _func(std::forward<Args>(args)...);
}
}
using info_type = rccl_api_info<TableIdx, OpIdx>;
ROCP_ERROR << "nullptr to next hip function for " << info_type::name << " ("
<< info_type::operation_idx << ")";
return get_default_retval<return_type>();
}
template <size_t TableIdx, size_t OpIdx>
template <typename RetT, typename... Args>
RetT
rccl_api_impl<TableIdx, OpIdx>::functor(Args... args)
{
using info_type = rccl_api_info<TableIdx, OpIdx>;
using callback_api_data_t = typename rccl_domain_info<TableIdx>::callback_data_type;
using buffered_api_data_t = typename rccl_domain_info<TableIdx>::buffer_data_type;
constexpr auto external_corr_id_domain_idx =
rccl_domain_info<TableIdx>::external_correlation_id_domain_idx;
if(registration::get_fini_status() != 0)
{
[[maybe_unused]] auto _ret = exec(info_type::get_table_func(), std::forward<Args>(args)...);
if constexpr(!std::is_void<RetT>::value)
return _ret;
else
return;
}
constexpr auto ref_count = 2;
auto thr_id = common::get_tid();
auto callback_contexts = tracing::callback_context_data_vec_t{};
auto buffered_contexts = tracing::buffered_context_data_vec_t{};
auto external_corr_ids = tracing::external_correlation_id_map_t{};
tracing::populate_contexts(info_type::callback_domain_idx,
info_type::buffered_domain_idx,
info_type::operation_idx,
callback_contexts,
buffered_contexts,
external_corr_ids);
if(callback_contexts.empty() && buffered_contexts.empty())
{
[[maybe_unused]] auto _ret = exec(info_type::get_table_func(), std::forward<Args>(args)...);
if constexpr(!std::is_void<RetT>::value)
return _ret;
else
return;
}
auto buffer_record = common::init_public_api_struct(buffered_api_data_t{});
auto tracer_data = common::init_public_api_struct(callback_api_data_t{});
auto* corr_id = tracing::correlation_service::construct(ref_count);
auto internal_corr_id = corr_id->internal;
tracing::populate_external_correlation_ids(external_corr_ids,
thr_id,
external_corr_id_domain_idx,
info_type::operation_idx,
internal_corr_id);
// invoke the callbacks
if(!callback_contexts.empty())
{
set_data_args(info_type::get_api_data_args(tracer_data.args), std::forward<Args>(args)...);
tracing::execute_phase_enter_callbacks(callback_contexts,
thr_id,
internal_corr_id,
external_corr_ids,
info_type::callback_domain_idx,
info_type::operation_idx,
tracer_data);
}
// enter callback may update the external correlation id field
tracing::update_external_correlation_ids(
external_corr_ids, thr_id, external_corr_id_domain_idx);
// record the start timestamp as close to the function call as possible
if(!buffered_contexts.empty())
{
buffer_record.start_timestamp = common::timestamp_ns();
}
// decrement the reference count before invoking
corr_id->sub_ref_count();
auto _ret = exec(info_type::get_table_func(), std::forward<Args>(args)...);
// record the end timestamp as close to the function call as possible
if(!buffered_contexts.empty())
{
buffer_record.end_timestamp = common::timestamp_ns();
}
if(!callback_contexts.empty())
{
set_data_retval(tracer_data.retval, _ret);
tracing::execute_phase_exit_callbacks(callback_contexts,
external_corr_ids,
info_type::callback_domain_idx,
info_type::operation_idx,
tracer_data);
}
if(!buffered_contexts.empty())
{
tracing::execute_buffer_record_emplace(buffered_contexts,
thr_id,
internal_corr_id,
external_corr_ids,
info_type::buffered_domain_idx,
info_type::operation_idx,
buffer_record);
}
// decrement the reference count after usage in the callback/buffers
corr_id->sub_ref_count();
context::pop_latest_correlation_id(corr_id);
if constexpr(!std::is_void<RetT>::value) return _ret;
}
} // namespace rccl
} // namespace rocprofiler
#define ROCPROFILER_LIB_ROCPROFILER_SDK_RCCL_RCCL_CPP_IMPL 1
// template specializations
#include "rccl.def.cpp"
namespace rocprofiler
{
namespace rccl
{
namespace
{
template <size_t TableIdx, size_t OpIdx, size_t... OpIdxTail>
const char*
name_by_id(const uint32_t id, std::index_sequence<OpIdx, OpIdxTail...>)
{
if(OpIdx == id) return rccl_api_info<TableIdx, OpIdx>::name;
if constexpr(sizeof...(OpIdxTail) > 0)
return name_by_id<TableIdx>(id, std::index_sequence<OpIdxTail...>{});
else
return nullptr;
}
template <size_t TableIdx, size_t OpIdx, size_t... OpIdxTail>
uint32_t
id_by_name(const char* name, std::index_sequence<OpIdx, OpIdxTail...>)
{
if(std::string_view{rccl_api_info<TableIdx, OpIdx>::name} == std::string_view{name})
return rccl_api_info<TableIdx, OpIdx>::operation_idx;
if constexpr(sizeof...(OpIdxTail) > 0)
return id_by_name<TableIdx>(name, std::index_sequence<OpIdxTail...>{});
else
return rccl_domain_info<TableIdx>::none;
}
template <size_t TableIdx, size_t OpIdx, size_t... OpIdxTail>
void
get_ids(std::vector<uint32_t>& _id_list, std::index_sequence<OpIdx, OpIdxTail...>)
{
auto _idx = rccl_api_info<TableIdx, OpIdx>::operation_idx;
if(_idx < rccl_domain_info<TableIdx>::last) _id_list.emplace_back(_idx);
if constexpr(sizeof...(OpIdxTail) > 0)
get_ids<TableIdx>(_id_list, std::index_sequence<OpIdxTail...>{});
}
template <size_t TableIdx, size_t OpIdx, size_t... OpIdxTail>
void
get_names(std::vector<const char*>& _name_list, std::index_sequence<OpIdx, OpIdxTail...>)
{
auto&& _name = rccl_api_info<TableIdx, OpIdx>::name;
if(_name != nullptr && strnlen(_name, 1) > 0) _name_list.emplace_back(_name);
if constexpr(sizeof...(OpIdxTail) > 0)
get_names<TableIdx>(_name_list, std::index_sequence<OpIdxTail...>{});
}
template <size_t TableIdx, typename DataT, size_t OpIdx, size_t... OpIdxTail>
void
iterate_args(const uint32_t id,
const DataT& data,
rocprofiler_callback_tracing_operation_args_cb_t func,
int32_t max_deref,
void* user_data,
std::index_sequence<OpIdx, OpIdxTail...>)
{
if(OpIdx == id)
{
using info_type = rccl_api_info<TableIdx, OpIdx>;
auto&& arg_list = info_type::as_arg_list(data, max_deref);
auto&& arg_addr = info_type::as_arg_addr(data);
for(size_t i = 0; i < std::min(arg_list.size(), arg_addr.size()); ++i)
{
auto ret = func(info_type::callback_domain_idx, // kind
id, // operation
i, // arg_number
arg_addr.at(i), // arg_value_addr
arg_list.at(i).indirection_level, // indirection
arg_list.at(i).type, // arg_type
arg_list.at(i).name, // arg_name
arg_list.at(i).value.c_str(), // arg_value_str
arg_list.at(i).dereference_count, // num deref in str
user_data);
if(ret != 0) break;
}
return;
}
if constexpr(sizeof...(OpIdxTail) > 0)
iterate_args<TableIdx>(
id, data, func, max_deref, user_data, std::index_sequence<OpIdxTail...>{});
}
bool
should_wrap_functor(rocprofiler_callback_tracing_kind_t _callback_domain,
rocprofiler_buffer_tracing_kind_t _buffered_domain,
int _operation)
{
// we loop over all the *registered* contexts and see if any of them, at any point in time,
// might require callback or buffered API tracing
for(const auto& itr : context::get_registered_contexts())
{
if(!itr) continue;
// if there is a callback tracer enabled for the given domain and op, we need to wrap
if(itr->callback_tracer && itr->callback_tracer->domains(_callback_domain) &&
itr->callback_tracer->domains(_callback_domain, _operation))
return true;
// if there is a buffered tracer enabled for the given domain and op, we need to wrap
if(itr->buffered_tracer && itr->buffered_tracer->domains(_buffered_domain) &&
itr->buffered_tracer->domains(_buffered_domain, _operation))
return true;
}
return false;
}
template <size_t TableIdx, typename Tp, size_t OpIdx>
void
copy_table(Tp* _orig, uint64_t _tbl_instance, std::integral_constant<size_t, OpIdx>)
{
using table_type = typename rccl_table_lookup<TableIdx>::type;
if constexpr(std::is_same<table_type, Tp>::value)
{
auto _info = rccl_api_info<TableIdx, OpIdx>{};
// make sure we don't access a field that doesn't exist in input table
if(_info.offset() >= _orig->size) return;
// 1. get the sub-table containing the function pointer in original table
// 2. get reference to function pointer in sub-table in original table
auto& _orig_table = _info.get_table(_orig);
auto& _orig_func = _info.get_table_func(_orig_table);
// 3. get the sub-table containing the function pointer in saved table
// 4. get reference to function pointer in sub-table in saved table
// 5. save the original function in the saved table
auto& _copy_table = _info.get_table(*get_table<TableIdx>());
auto& _copy_func = _info.get_table_func(_copy_table);
ROCP_FATAL_IF(_copy_func && _tbl_instance == 0)
<< _info.name << " has non-null function pointer " << _copy_func
<< " despite this being the first instance of the library being copies";
if(!_copy_func)
{
ROCP_TRACE << "copying table entry for " << _info.name;
_copy_func = _orig_func;
}
else
{
ROCP_TRACE << "skipping copying table entry for " << _info.name
<< " from table instance " << _tbl_instance;
}
}
}
template <size_t TableIdx, typename Tp, size_t OpIdx>
void
update_table(Tp* _orig, std::integral_constant<size_t, OpIdx>)
{
using table_type = typename rccl_table_lookup<TableIdx>::type;
if constexpr(std::is_same<table_type, Tp>::value)
{
auto _info = rccl_api_info<TableIdx, OpIdx>{};
// make sure we don't access a field that doesn't exist in input table
if(_info.offset() >= _orig->size) return;
// check to see if there are any contexts which enable this operation in the HIP API domain
if(!should_wrap_functor(
_info.callback_domain_idx, _info.buffered_domain_idx, _info.operation_idx))
return;
ROCP_TRACE << "updating table entry for " << _info.name;
// 1. get the sub-table containing the function pointer in original table
// 2. get reference to function pointer in sub-table in original table
// 3. update function pointer with wrapper
auto& _table = _info.get_table(_orig);
auto& _func = _info.get_table_func(_table);
_func = _info.get_functor(_func);
}
}
template <size_t TableIdx, typename Tp, size_t OpIdx, size_t... OpIdxTail>
void
copy_table(Tp* _orig, uint64_t _tbl_instance, std::index_sequence<OpIdx, OpIdxTail...>)
{
copy_table<TableIdx>(_orig, _tbl_instance, std::integral_constant<size_t, OpIdx>{});
if constexpr(sizeof...(OpIdxTail) > 0)
copy_table<TableIdx>(_orig, _tbl_instance, std::index_sequence<OpIdxTail...>{});
}
template <size_t TableIdx, typename Tp, size_t OpIdx, size_t... OpIdxTail>
void
update_table(Tp* _orig, std::index_sequence<OpIdx, OpIdxTail...>)
{
update_table<TableIdx>(_orig, std::integral_constant<size_t, OpIdx>{});
if constexpr(sizeof...(OpIdxTail) > 0)
update_table<TableIdx>(_orig, std::index_sequence<OpIdxTail...>{});
}
} // namespace
// check out the assembly here... this compiles to a switch statement
template <size_t TableIdx>
const char*
name_by_id(uint32_t id)
{
return name_by_id<TableIdx>(id, std::make_index_sequence<rccl_domain_info<TableIdx>::last>{});
}
template <size_t TableIdx>
uint32_t
id_by_name(const char* name)
{
return id_by_name<TableIdx>(name, std::make_index_sequence<rccl_domain_info<TableIdx>::last>{});
}
template <size_t TableIdx>
std::vector<uint32_t>
get_ids()
{
constexpr auto last_api_id = rccl_domain_info<TableIdx>::last;
auto _data = std::vector<uint32_t>{};
_data.reserve(last_api_id);
get_ids<TableIdx>(_data, std::make_index_sequence<last_api_id>{});
return _data;
}
template <size_t TableIdx>
std::vector<const char*>
get_names()
{
constexpr auto last_api_id = rccl_domain_info<TableIdx>::last;
auto _data = std::vector<const char*>{};
_data.reserve(last_api_id);
get_names<TableIdx>(_data, std::make_index_sequence<last_api_id>{});
return _data;
}
template <size_t TableIdx>
void
iterate_args(uint32_t id,
const rocprofiler_callback_tracing_hip_api_data_t& data,
rocprofiler_callback_tracing_operation_args_cb_t callback,
int32_t max_deref,
void* user_data)
{
if(callback)
iterate_args<TableIdx>(id,
data,
callback,
max_deref,
user_data,
std::make_index_sequence<rccl_domain_info<TableIdx>::last>{});
}
template <typename TableT>
void
copy_table(TableT* _orig, uint64_t _tbl_instance)
{
constexpr auto TableIdx = rccl_table_id_lookup<TableT>::value;
if(_orig)
copy_table<TableIdx>(
_orig, _tbl_instance, std::make_index_sequence<rccl_domain_info<TableIdx>::last>{});
}
template <typename TableT>
void
update_table(TableT* _orig)
{
constexpr auto TableIdx = rccl_table_id_lookup<TableT>::value;
if(_orig)
update_table<TableIdx>(_orig, std::make_index_sequence<rccl_domain_info<TableIdx>::last>{});
}
using rccl_api_data_t = rocprofiler_callback_tracing_rccl_api_data_t;
using rccl_op_args_cb_t = rocprofiler_callback_tracing_operation_args_cb_t;
#define INSTANTIATE_RCCL_TABLE_FUNC(TABLE_TYPE, TABLE_IDX) \
template void copy_table<TABLE_TYPE>(TABLE_TYPE * _tbl, uint64_t _instv); \
template void update_table<TABLE_TYPE>(TABLE_TYPE * _tbl); \
template const char* name_by_id<TABLE_IDX>(uint32_t); \
template uint32_t id_by_name<TABLE_IDX>(const char*); \
template std::vector<uint32_t> get_ids<TABLE_IDX>(); \
template std::vector<const char*> get_names<TABLE_IDX>();
INSTANTIATE_RCCL_TABLE_FUNC(rccl_api_func_table_t, ROCPROFILER_RCCL_TABLE_ID)
} // namespace rccl
} // namespace rocprofiler
+109
Dosyayı Görüntüle
@@ -0,0 +1,109 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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.
#include "lib/rocprofiler-sdk/rccl/defines.hpp"
#include "lib/rocprofiler-sdk/rccl/rccl.hpp"
#include <rocprofiler-sdk/external_correlation.h>
#include <rocprofiler-sdk/fwd.h>
#include <rocprofiler-sdk/rccl.h>
#include <rocprofiler-sdk/rccl/table_id.h>
namespace rocprofiler
{
namespace rccl
{
template <>
struct rccl_domain_info<ROCPROFILER_RCCL_TABLE_ID_LAST>
{
using args_type = rocprofiler_rccl_api_args_t;
using retval_type = rocprofiler_rccl_api_retval_t;
using callback_data_type = rocprofiler_callback_tracing_rccl_api_data_t;
using buffer_data_type = rocprofiler_buffer_tracing_rccl_api_record_t;
};
template <>
struct rccl_domain_info<ROCPROFILER_RCCL_TABLE_ID>
: rccl_domain_info<ROCPROFILER_RCCL_TABLE_ID_LAST>
{
using enum_type = rocprofiler_marker_core_api_id_t;
static constexpr auto callback_domain_idx = ROCPROFILER_CALLBACK_TRACING_RCCL_API;
static constexpr auto buffered_domain_idx = ROCPROFILER_BUFFER_TRACING_RCCL_API;
static constexpr auto none = ROCPROFILER_RCCL_API_ID_NONE;
static constexpr auto last = ROCPROFILER_RCCL_API_ID_LAST;
static constexpr auto external_correlation_id_domain_idx =
ROCPROFILER_EXTERNAL_CORRELATION_REQUEST_RCCL_API;
};
} // namespace rccl
} // namespace rocprofiler
#if defined(ROCPROFILER_LIB_ROCPROFILER_SDK_RCCL_RCCL_CPP_IMPL) && \
ROCPROFILER_LIB_ROCPROFILER_SDK_RCCL_RCCL_CPP_IMPL == 1
// clang-format off
RCCL_API_TABLE_LOOKUP_DEFINITION(ROCPROFILER_RCCL_TABLE_ID, rccl_api_func_table_t)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclAllGather, ncclAllGather, ncclAllGather_fn, sendbuff, recvbuff, sendcount, datatype, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclAllReduce, ncclAllReduce, ncclAllReduce_fn, sendbuff, recvbuff, count, datatype, op, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclAllToAll, ncclAllToAll, ncclAllToAll_fn, sendbuff, recvbuff, count, datatype, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclAllToAllv, ncclAllToAllv, ncclAllToAllv_fn, sendbuff, sendcounts, sdispls, recvbuff, recvcounts, rdispls, datatype, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclBroadcast, ncclBroadcast, ncclBroadcast_fn, sendbuff, recvbuff, count, datatype, root, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclGather, ncclGather, ncclGather_fn, sendbuff, recvbuff, sendcount, datatype, root, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclReduce, ncclReduce, ncclReduce_fn, sendbuff, recvbuff, count, datatype, op, root, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclReduceScatter, ncclReduceScatter, ncclReduceScatter_fn, sendbuff, recvbuff, recvcount, datatype, op, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclScatter, ncclScatter, ncclScatter_fn, sendbuff, recvbuff, recvcount, datatype, root, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclSend, ncclSend, ncclSend_fn, sendbuff, count, datatype, peer, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclRecv, ncclRecv, ncclRecv_fn, recvbuff, count, datatype, peer, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclRedOpCreatePreMulSum, ncclRedOpCreatePreMulSum, ncclRedOpCreatePreMulSum_fn, op, scalar, datatype, residence, comm)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclRedOpDestroy, ncclRedOpDestroy, ncclRedOpDestroy_fn, op, comm)
RCCL_API_INFO_DEFINITION_0(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclGroupStart, ncclGroupStart, ncclGroupStart_fn)
RCCL_API_INFO_DEFINITION_0(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclGroupEnd, ncclGroupEnd, ncclGroupEnd_fn)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclGetVersion, ncclGetVersion, ncclGetVersion_fn, version)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclGetUniqueId, ncclGetUniqueId, ncclGetUniqueId_fn, out)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommInitRank, ncclCommInitRank, ncclCommInitRank_fn, newcomm, nranks, commId, myrank)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommInitAll, ncclCommInitAll, ncclCommInitAll_fn, comms, ndev, devlist)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommInitRankConfig, ncclCommInitRankConfig, ncclCommInitRankConfig_fn, comm, nranks, commId, myrank, config)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommFinalize, ncclCommFinalize, ncclCommFinalize_fn, comm)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommDestroy, ncclCommDestroy, ncclCommDestroy_fn, comm)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommAbort, ncclCommAbort, ncclCommAbort_fn, comm)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommSplit, ncclCommSplit, ncclCommSplit_fn, comm, color, key, newcomm, config)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclGetErrorString, ncclGetErrorString, ncclGetErrorString_fn, code)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclGetLastError, ncclGetLastError, ncclGetLastError_fn, comm)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommGetAsyncError, ncclCommGetAsyncError, ncclCommGetAsyncError_fn, comm, asyncError)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommCount, ncclCommCount, ncclCommCount_fn, comm, count)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommCuDevice, ncclCommCuDevice, ncclCommCuDevice_fn, comm, devid)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommUserRank, ncclCommUserRank, ncclCommUserRank_fn, comm, rank)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclMemAlloc, ncclMemAlloc, ncclMemAlloc_fn, ptr, size)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclMemFree, ncclMemFree, ncclMemFree_fn, ptr)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_mscclLoadAlgo, mscclLoadAlgo, mscclLoadAlgo_fn, mscclAlgoFilePath, mscclAlgoHandle, rank)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_mscclRunAlgo, mscclRunAlgo, mscclRunAlgo_fn, sendBuff, sendCounts, sDisPls, recvBuff, recvCounts, rDisPls, count, dataType, root, peer, op, mscclAlgoHandle, comm, stream)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_mscclUnloadAlgo, mscclUnloadAlgo, mscclUnloadAlgo_fn, mscclAlgoHandle)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommRegister, ncclCommRegister, ncclCommRegister_fn, comm, buff, size, handle)
RCCL_API_INFO_DEFINITION_V(ROCPROFILER_RCCL_TABLE_ID, ROCPROFILER_RCCL_API_ID_ncclCommDeregister, ncclCommDeregister, ncclCommDeregister_fn, comm, handle)
#else
# error \
"Do not compile this file directly. It is included by lib/rocprofiler-sdk/rccl/rccl.cpp"
#endif
+123
Dosyayı Görüntüle
@@ -0,0 +1,123 @@
// MIT License
//
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
//
// 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
#if !defined(ROCPROFILER_SDK_RCCL_HAS_API_TRACE)
# if defined __has_include
# if __has_include(<rccl/amd_detail/api_trace.h>)
# define ROCPROFILER_SDK_RCCL_HAS_API_TRACE 1
# else
# define ROCPROFILER_SDK_RCCL_HAS_API_TRACE 0
# endif
# else
# define ROCPROFILER_SDK_RCCL_HAS_API_TRACE 0
# endif
#endif
#if ROCPROFILER_SDK_RCCL_HAS_API_TRACE > 0
# include <rccl/amd_detail/api_trace.h>
#else
# include "lib/rocprofiler-sdk/rccl/details/api_trace.h"
#endif
#include <rocprofiler-sdk/rocprofiler.h>
#include <rccl/rccl.h>
#include <cstdint>
#include <vector>
namespace rocprofiler
{
namespace rccl
{
using rccl_api_func_table_t = ::rcclApiFuncTable;
struct RcclAPITable
{
rccl_api_func_table_t* rccl_api_table = nullptr;
};
using rccl_api_table_t = RcclAPITable;
rccl_api_table_t&
get_table();
template <size_t OpIdx>
struct rccl_table_lookup;
template <typename Tp>
struct rccl_table_id_lookup;
template <size_t TableIdx>
struct rccl_domain_info;
template <size_t TableIdx, size_t OpIdx>
struct rccl_api_info;
template <size_t TableIdx, size_t OpIdx>
struct rccl_api_impl : rccl_domain_info<TableIdx>
{
template <typename DataArgsT, typename... Args>
static auto set_data_args(DataArgsT&, Args... args);
template <typename FuncT, typename... Args>
static auto exec(FuncT&&, Args&&... args);
template <typename RetT, typename... Args>
static RetT functor(Args... args);
};
template <size_t TableIdx>
const char*
name_by_id(uint32_t id);
template <size_t TableIdx>
uint32_t
id_by_name(const char* name);
template <size_t TableIdx>
std::vector<const char*>
get_names();
template <size_t TableIdx>
std::vector<uint32_t>
get_ids();
template <size_t TableIdx>
void
iterate_args(uint32_t id,
const rocprofiler_callback_tracing_rccl_api_data_t& data,
rocprofiler_callback_tracing_operation_args_cb_t callback,
int32_t max_deref,
void* user_data);
template <typename TableT>
void
copy_table(TableT* _orig, uint64_t _tbl_instance);
template <typename TableT>
void
update_table(TableT* _orig);
} // namespace rccl
} // namespace rocprofiler
+20
Dosyayı Görüntüle
@@ -43,6 +43,7 @@
#include "lib/rocprofiler-sdk/page_migration/page_migration.hpp"
#include "lib/rocprofiler-sdk/pc_sampling/code_object.hpp"
#include "lib/rocprofiler-sdk/pc_sampling/service.hpp"
#include "lib/rocprofiler-sdk/rccl/rccl.hpp"
#include <rocprofiler-sdk/context.h>
#include <rocprofiler-sdk/fwd.h>
@@ -846,6 +847,25 @@ rocprofiler_set_api_table(const char* name,
rocprofiler::intercept_table::notify_intercept_table_registration(
ROCPROFILER_MARKER_NAME_TABLE, lib_version, lib_instance, std::make_tuple(roctx_name));
}
else if(std::string_view{name} == "rccl")
{
// pass to rccl init
ROCP_ERROR_IF(num_tables > 1)
<< "rocprofiler expected RCCL library to pass 1 API table, not " << num_tables;
auto* rccl_api = static_cast<rcclApiFuncTable*>(tables[0]);
// any internal modifications to the rcclApiFuncTable need to be done before we make the
// copy or else those modifications will be lost when RCCL API tracing is enabled
// because the RCCL API tracing invokes the function pointers from the copy below
rocprofiler::rccl::copy_table(rccl_api, lib_instance);
// install rocprofiler API wrappers
rocprofiler::rccl::update_table(rccl_api);
rocprofiler::intercept_table::notify_intercept_table_registration(
ROCPROFILER_RCCL_TABLE, lib_version, lib_instance, std::make_tuple(rccl_api));
}
else
{
ROCP_ERROR << "rocprofiler does not accept API tables from " << name;
+131 -9
Dosyayı Görüntüle
@@ -344,6 +344,23 @@ struct marker_api_callback_record_t
}
};
struct rccl_api_callback_record_t
{
uint64_t timestamp = 0;
rocprofiler_callback_tracing_record_t record = {};
rocprofiler_callback_tracing_rccl_api_data_t payload = {};
callback_arg_array_t args = {};
template <typename ArchiveT>
void save(ArchiveT& ar) const
{
ar(cereal::make_nvp("timestamp", timestamp));
cereal::save(ar, record);
ar(cereal::make_nvp("payload", payload));
serialize_args(ar, args);
}
};
struct kernel_dispatch_callback_record_t
{
uint64_t timestamp = 0;
@@ -466,6 +483,7 @@ auto hip_api_cb_records = std::deque<hip_api_callback_record_t>{};
auto scratch_memory_cb_records = std::deque<scratch_memory_callback_record_t>{};
auto kernel_dispatch_cb_records = std::deque<kernel_dispatch_callback_record_t>{};
auto memory_copy_cb_records = std::deque<memory_copy_callback_record_t>{};
auto rccl_api_cb_records = std::deque<rccl_api_callback_record_t>{};
int
set_external_correlation_id(rocprofiler_thread_id_t thr_id,
@@ -678,6 +696,19 @@ tool_tracing_callback(rocprofiler_callback_tracing_record_t record,
auto _lk = std::unique_lock<std::mutex>{_mutex};
memory_copy_cb_records.emplace_back(memory_copy_callback_record_t{ts, record, *data});
}
else if(record.kind == ROCPROFILER_CALLBACK_TRACING_RCCL_API)
{
auto* data = static_cast<rocprofiler_callback_tracing_rccl_api_data_t*>(record.payload);
auto args = callback_arg_array_t{};
if(record.phase == ROCPROFILER_CALLBACK_PHASE_EXIT)
rocprofiler_iterate_callback_tracing_kind_operation_args(
record, save_args, record.phase, &args);
static auto _mutex = std::mutex{};
auto _lk = std::unique_lock<std::mutex>{_mutex};
rccl_api_cb_records.emplace_back(
rccl_api_callback_record_t{ts, record, *data, std::move(args)});
}
else
{
throw std::runtime_error{"unsupported callback kind"};
@@ -693,6 +724,7 @@ auto scratch_memory_records = std::deque<rocprofiler_buffer_tracing_scratch_
auto page_migration_records = std::deque<rocprofiler_buffer_tracing_page_migration_record_t>{};
auto corr_id_retire_records =
std::deque<rocprofiler_buffer_tracing_correlation_id_retirement_record_t>{};
auto rccl_api_bf_records = std::deque<rocprofiler_buffer_tracing_rccl_api_record_t>{};
void
tool_tracing_buffered(rocprofiler_context_id_t /*context*/,
@@ -790,6 +822,13 @@ tool_tracing_buffered(rocprofiler_context_id_t /*context*/,
corr_id_retire_records.emplace_back(*record);
}
else if(header->kind == ROCPROFILER_BUFFER_TRACING_RCCL_API)
{
auto* record =
static_cast<rocprofiler_buffer_tracing_rccl_api_record_t*>(header->payload);
rccl_api_bf_records.emplace_back(*record);
}
else
{
throw std::runtime_error{
@@ -869,11 +908,13 @@ rocprofiler_context_id_t hsa_api_callback_ctx = {};
rocprofiler_context_id_t hip_api_callback_ctx = {};
rocprofiler_context_id_t marker_api_callback_ctx = {};
rocprofiler_context_id_t code_object_ctx = {};
rocprofiler_context_id_t rccl_api_callback_ctx = {};
rocprofiler_context_id_t hsa_api_buffered_ctx = {};
rocprofiler_context_id_t hip_api_buffered_ctx = {};
rocprofiler_context_id_t marker_api_buffered_ctx = {};
rocprofiler_context_id_t memory_copy_callback_ctx = {};
rocprofiler_context_id_t memory_copy_buffered_ctx = {};
rocprofiler_context_id_t rccl_api_buffered_ctx = {};
rocprofiler_context_id_t counter_collection_ctx = {};
rocprofiler_context_id_t scratch_memory_ctx = {};
rocprofiler_context_id_t corr_id_retire_ctx = {};
@@ -890,6 +931,7 @@ rocprofiler_buffer_id_t page_migration_buffer = {};
rocprofiler_buffer_id_t counter_collection_buffer = {};
rocprofiler_buffer_id_t scratch_memory_buffer = {};
rocprofiler_buffer_id_t corr_id_retire_buffer = {};
rocprofiler_buffer_id_t rccl_api_buffered_buffer = {};
auto contexts = std::unordered_map<std::string_view, rocprofiler_context_id_t*>{
{"HSA_API_CALLBACK", &hsa_api_callback_ctx},
@@ -898,6 +940,7 @@ auto contexts = std::unordered_map<std::string_view, rocprofiler_context_id_t*>{
{"CODE_OBJECT", &code_object_ctx},
{"KERNEL_DISPATCH_CALLBACK", &kernel_dispatch_callback_ctx},
{"MEMORY_COPY_CALLBACK", &memory_copy_callback_ctx},
{"RCCL_API_CALLBACK", &rccl_api_callback_ctx},
{"HSA_API_BUFFERED", &hsa_api_buffered_ctx},
{"HIP_API_BUFFERED", &hip_api_buffered_ctx},
{"MARKER_API_BUFFERED", &marker_api_buffered_ctx},
@@ -907,17 +950,19 @@ auto contexts = std::unordered_map<std::string_view, rocprofiler_context_id_t*>{
{"COUNTER_COLLECTION", &counter_collection_ctx},
{"SCRATCH_MEMORY", &scratch_memory_ctx},
{"CORRELATION_ID_RETIREMENT", &corr_id_retire_ctx},
{"RCCL_API_BUFFERED", &rccl_api_buffered_ctx},
};
auto buffers = std::array<rocprofiler_buffer_id_t*, 9>{&hsa_api_buffered_buffer,
&hip_api_buffered_buffer,
&marker_api_buffered_buffer,
&kernel_dispatch_buffer,
&memory_copy_buffer,
&scratch_memory_buffer,
&page_migration_buffer,
&counter_collection_buffer,
&corr_id_retire_buffer};
auto buffers = std::array<rocprofiler_buffer_id_t*, 10>{&hsa_api_buffered_buffer,
&hip_api_buffered_buffer,
&marker_api_buffered_buffer,
&kernel_dispatch_buffer,
&memory_copy_buffer,
&scratch_memory_buffer,
&page_migration_buffer,
&counter_collection_buffer,
&corr_id_retire_buffer,
&rccl_api_buffered_buffer};
auto agents = std::vector<rocprofiler_agent_t>{};
auto agents_map = std::unordered_map<rocprofiler_agent_id_t, rocprofiler_agent_t>{};
@@ -1056,6 +1101,18 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
nullptr),
"scratch memory tracing service configure");
{
auto _status =
rocprofiler_configure_callback_tracing_service(rccl_api_callback_ctx,
ROCPROFILER_CALLBACK_TRACING_RCCL_API,
nullptr,
0,
tool_tracing_callback,
nullptr);
if(_status != ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED)
ROCPROFILER_CALL(_status, "rccl api callback tracing service configure");
}
constexpr auto buffer_size = 8192;
constexpr auto watermark = 7936;
@@ -1140,6 +1197,15 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
&counter_collection_buffer),
"buffer creation");
ROCPROFILER_CALL(rocprofiler_create_buffer(rccl_api_buffered_ctx,
buffer_size,
watermark,
ROCPROFILER_BUFFER_POLICY_LOSSLESS,
tool_tracing_buffered,
tool_data,
&rccl_api_buffered_buffer),
"buffer creation");
for(auto itr : {ROCPROFILER_BUFFER_TRACING_HSA_CORE_API,
ROCPROFILER_BUFFER_TRACING_HSA_AMD_EXT_API,
ROCPROFILER_BUFFER_TRACING_HSA_IMAGE_EXT_API,
@@ -1231,6 +1297,17 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
corr_id_retire_buffer),
"buffer tracing service for memory copy configure");
{
auto _status =
rocprofiler_configure_buffer_tracing_service(rccl_api_buffered_ctx,
ROCPROFILER_BUFFER_TRACING_RCCL_API,
nullptr,
0,
rccl_api_buffered_buffer);
if(_status != ROCPROFILER_STATUS_ERROR_NOT_IMPLEMENTED)
ROCPROFILER_CALL(_status, "buffer tracing service configure");
}
ROCPROFILER_CALL(
rocprofiler_configure_buffered_dispatch_profile_counting_service(
counter_collection_ctx, counter_collection_buffer, dispatch_callback, nullptr),
@@ -1377,6 +1454,7 @@ tool_fini(void* tool_data)
<< ", scratch_memory_callback_records=" << scratch_memory_cb_records.size()
<< ", kernel_dispatch_callback_records=" << kernel_dispatch_cb_records.size()
<< ", memory_copy_callback_records=" << memory_copy_cb_records.size()
<< ", rccl_api_callback_records=" << rccl_api_cb_records.size()
<< ", kernel_dispatch_bf_records=" << kernel_dispatch_bf_records.size()
<< ", memory_copy_bf_records=" << memory_copy_bf_records.size()
<< ", scratch_memory_records=" << scratch_memory_records.size()
@@ -1385,6 +1463,7 @@ tool_fini(void* tool_data)
<< ", hip_api_bf_records=" << hip_api_bf_records.size()
<< ", marker_api_bf_records=" << marker_api_bf_records.size()
<< ", corr_id_retire_records=" << corr_id_retire_records.size()
<< ", rccl_api_bf_records=" << rccl_api_bf_records.size()
<< ", counter_collection_value_records=" << counter_collection_bf_records.size()
<< "...\n"
<< std::flush;
@@ -1474,6 +1553,7 @@ write_json(call_stack_t* _call_stack)
json_ar(cereal::make_nvp("hsa_api_traces", hsa_api_cb_records));
json_ar(cereal::make_nvp("hip_api_traces", hip_api_cb_records));
json_ar(cereal::make_nvp("marker_api_traces", marker_api_cb_records));
json_ar(cereal::make_nvp("rccl_api_traces", rccl_api_cb_records));
json_ar(cereal::make_nvp("scratch_memory_traces", scratch_memory_cb_records));
json_ar(cereal::make_nvp("kernel_dispatch", kernel_dispatch_cb_records));
json_ar(cereal::make_nvp("memory_copies", memory_copy_cb_records));
@@ -1497,6 +1577,7 @@ write_json(call_stack_t* _call_stack)
json_ar(cereal::make_nvp("hsa_api_traces", hsa_api_bf_records));
json_ar(cereal::make_nvp("hip_api_traces", hip_api_bf_records));
json_ar(cereal::make_nvp("marker_api_traces", marker_api_bf_records));
json_ar(cereal::make_nvp("rccl_api_traces", rccl_api_bf_records));
json_ar(cereal::make_nvp("retired_correlation_ids", corr_id_retire_records));
json_ar(cereal::make_nvp("counter_collection", counter_collection_bf_records));
} catch(std::exception& e)
@@ -1565,6 +1646,8 @@ write_perfetto()
tids.emplace(itr.thread_id);
for(auto itr : marker_api_bf_records)
tids.emplace(itr.thread_id);
for(auto itr : rccl_api_bf_records)
tids.emplace(itr.thread_id);
for(auto itr : memory_copy_bf_records)
{
@@ -1743,6 +1826,45 @@ write_perfetto()
itr.end_timestamp);
}
for(auto itr : rccl_api_bf_records)
{
auto name = buffer_names.at(itr.kind, itr.operation);
auto& track = thread_tracks.at(itr.thread_id);
auto _args = callback_arg_array_t{};
auto ritr = std::find_if(
rccl_api_cb_records.begin(), rccl_api_cb_records.end(), [&itr](const auto& citr) {
return (citr.record.correlation_id.internal == itr.correlation_id.internal &&
!citr.args.empty());
});
if(ritr != rccl_api_cb_records.end()) _args = ritr->args;
TRACE_EVENT_BEGIN(sdk::perfetto_category<sdk::category::rccl_api>::name,
::perfetto::StaticString(name.data()),
track,
itr.start_timestamp,
::perfetto::Flow::ProcessScoped(itr.correlation_id.internal),
"begin_ns",
itr.start_timestamp,
"tid",
itr.thread_id,
"kind",
itr.kind,
"operation",
itr.operation,
"corr_id",
itr.correlation_id.internal,
[&](::perfetto::EventContext ctx) {
for(const auto& aitr : _args)
sdk::add_perfetto_annotation(ctx, aitr.first, aitr.second);
});
TRACE_EVENT_END(sdk::perfetto_category<sdk::category::rccl_api>::name,
track,
itr.end_timestamp,
"end_ns",
itr.end_timestamp);
}
for(auto itr : memory_copy_bf_records)
{
auto name = buffer_names.at(itr.kind, itr.operation);