From 13db6e1a4a97f00b14e78bb2926c0c9dd89c257e Mon Sep 17 00:00:00 2001 From: Gopesh Bhardwaj Date: Fri, 22 Nov 2024 12:05:11 +0530 Subject: [PATCH 1/2] SDK doc updates (#1183) * correcting usage example * rccl trace * Adding Navi power state limitation * Addressed feedback * kernel-rename * kokkos trace * more information on kookos tracing * Corecting tool library hardcoding * summary domains * Updating domain stats file * updating images * rocprofv3 default behavior update * Removing README from API documentation * Added missing description in Topics * Fixed wrong rendering of README in API document * Fixing Topics in API docs * Removing API doc for details/rccl.h * Addressed review comments (cherry picked from commit 7ea9ced4939f1e95a25ef4955f26546560b721b0) --- README.md | 19 +- source/docs/api-reference/tool_library.md | 2 +- .../comparing-with-legacy-tools.rst | 8 +- source/docs/data/hip_domain_stats.csv | 2 + source/docs/data/rccl_trace.csv | 22 +++ .../data/rocprofv3_hip_memcpy_summary.png | Bin 0 -> 36263 bytes source/docs/data/rocprofv3_memcpy_summary.png | Bin 0 -> 11246 bytes source/docs/data/rocprofv3_summary.png | Bin 0 -> 51795 bytes source/docs/how-to/using-rocprofv3.rst | 184 ++++++++++++++++-- source/docs/rocprofiler-sdk.dox.in | 8 +- .../rocprofiler-sdk/rccl/details/rccl.h | 28 +-- source/include/rocprofiler-sdk/registration.h | 2 +- source/include/rocprofiler-sdk/rocprofiler.h | 2 +- 13 files changed, 234 insertions(+), 43 deletions(-) create mode 100644 source/docs/data/hip_domain_stats.csv create mode 100644 source/docs/data/rccl_trace.csv create mode 100644 source/docs/data/rocprofv3_hip_memcpy_summary.png create mode 100644 source/docs/data/rocprofv3_memcpy_summary.png create mode 100644 source/docs/data/rocprofv3_summary.png diff --git a/README.md b/README.md index 8d2a5006..40ddcfa0 100644 --- a/README.md +++ b/README.md @@ -73,13 +73,24 @@ Please report in the Github Issues. - **Need for Cold Restart**: In the event of a hardware freeze, you may need to perform a cold restart (turning the hardware off and on) to restore normal operations. Please use this beta feature cautiously. It may affect your system's stability and performance. Proceed at your own risk. -- At this point, We do not recommend stress-testing the beta implementation. + - At this point, We do not recommend stress-testing the beta implementation. -- Correlation IDs provided by the PC sampling service are verified only for HIP API calls. + - Correlation IDs provided by the PC sampling service are verified only for HIP API calls. -- Timestamps in PC sampling records might not be 100% accurate. + - Timestamps in PC sampling records might not be 100% accurate. -- Using PC sampling on multi-threaded applications might fail with `HSA_STATUS_ERROR_EXCEPTION`.Furthermore, if three or more threads launch operations to the same agent, and if PC sampling is enabled, the `HSA_STATUS_ERROR_EXCEPTION` might appear. + - Using PC sampling on multi-threaded applications might fail with `HSA_STATUS_ERROR_EXCEPTION`.Furthermore, if three or more threads launch operations to the same agent, and if PC sampling is enabled, the `HSA_STATUS_ERROR_EXCEPTION` might appear. + +- Navi3x requires a stable power state for counter collection. + Currently, this state needs to be set by the user. + To do so, set "power_dpm_force_performance_level" to be writeable for non-root users, then set performance level to profile_standard: + + ```bash + sudo chmod 777 /sys/class/drm/card0/device/power_dpm_force_performance_level + echo profile_standard >> /sys/class/drm/card0/device/power_dpm_force_performance_level + ``` + + Recommended: "profile_standard" for counter collection and "auto" for all other profiling. Use rocm-smi to verify the current power state. For multiGPU systems (includes integrated graphics), replace "card0" by the desired card. > [!WARNING] > The latest mainline version of AQLprofile can be found at [https://repo.radeon.com/rocm/misc/aqlprofile/](https://repo.radeon.com/rocm/misc/aqlprofile/). However, it's important to note that updates to the public AQLProfile may not occur as frequently as updates to the rocprofiler-sdk. This discrepancy could lead to a potential mismatch between the AQLprofile binary and the rocprofiler-sdk source. diff --git a/source/docs/api-reference/tool_library.md b/source/docs/api-reference/tool_library.md index cce13d50..9ce1660e 100644 --- a/source/docs/api-reference/tool_library.md +++ b/source/docs/api-reference/tool_library.md @@ -7,7 +7,7 @@ myst: # ROCprofiler-SDK tool library -The tool library utilizes APIs from `rocprofiler-sdk` and `rocprofiler-register` libraries for profiling and tracing HIP applications. This document provides information to help you design a tool by utilizing the `rocprofiler-sdk` and `rocprofiler-register` libraries efficiently. The command-line tool `rocprofv3` is also built on `librocprofiler-sdk-tool.so.0.4.0`, which uses these libraries. +The tool library utilizes APIs from `rocprofiler-sdk` and `rocprofiler-register` libraries for profiling and tracing HIP applications. This document provides information to help you design a tool by utilizing the `rocprofiler-sdk` and `rocprofiler-register` libraries efficiently. The command-line tool `rocprofv3` is also built on `librocprofiler-sdk-tool.so.X.Y.Z`, which uses these libraries. ## ROCm runtimes design diff --git a/source/docs/conceptual/comparing-with-legacy-tools.rst b/source/docs/conceptual/comparing-with-legacy-tools.rst index 619a244c..16651196 100644 --- a/source/docs/conceptual/comparing-with-legacy-tools.rst +++ b/source/docs/conceptual/comparing-with-legacy-tools.rst @@ -383,4 +383,10 @@ ROCprofiler-SDK introduces a new command-line tool, `rocprofv3`, which is a more Timing Difference Between rocprofv3 and rocprofv1/v2 ======================================================== -Rocprofv3 has improved the accuracy of timing information by reducing the tool overhead required to collect data and reducing the interference to the timing of the kernel being measured. The result of this work is a reduction in variance of kernel times received for the same kernel execution and more accurate timing in general. These changes have not been backported (and will not be backported) to rocprofv1/v2, so there can be substantial (20%) differences in execution time reported by v1/v2 vs v3 for a single kernel execution. Over a large number of samples of the same kernel, the difference in average execution time is in the low single digit percentage time with a much tighter variance of results on rocprofv3. We have included testing in the test suite to verify the timing information outputted by rocprofv3 to ensure that the values we are returning are accurate. +``rocprofv3`` has improved the accuracy of timing information by reducing the tool overhead required to collect data and reducing the interference to the timing of the kernel being measured. The result of this work is a reduction in variance of kernel times received for the same kernel execution and more accurate timing in general. These changes have not been backported (and will not be backported) to rocprofv1/v2, so there can be substantial (20%) differences in execution time reported by v1/v2 vs v3 for a single kernel execution. Over a large number of samples of the same kernel, the difference in average execution time is in the low single digit percentage time with a much tighter variance of results on rocprofv3. We have included testing in the test suite to verify the timing information outputted by rocprofv3 to ensure that the values we are returning are accurate. + +======================================================== +Default run of rocprofv3 and rocprofv1/v2 +======================================================== + +``rocprofv3`` has a different default behavior than rocprofv1/v2 when being run without any option. The default behavior of rocprofv3 is to collect all available agents on the system and to output it in ``csv`` format. The default behavior of rocprofv1/v2 was to output the `kernel traces` in CSV format. In rocprofv3, kernel traces can be obtained by using ``--kernel-trace`` option. diff --git a/source/docs/data/hip_domain_stats.csv b/source/docs/data/hip_domain_stats.csv new file mode 100644 index 00000000..55cd0fc2 --- /dev/null +++ b/source/docs/data/hip_domain_stats.csv @@ -0,0 +1,2 @@ +"Name","Calls","TotalDurationNs","AverageNs","Percentage","MinNs","MaxNs","StdDev" +"HIP_API",13,458514859,35270373.769231,100.00,2300,352276613,99315857.546240 \ No newline at end of file diff --git a/source/docs/data/rccl_trace.csv b/source/docs/data/rccl_trace.csv new file mode 100644 index 00000000..6fee219c --- /dev/null +++ b/source/docs/data/rccl_trace.csv @@ -0,0 +1,22 @@ +"Domain","Function","Process_Id","Thread_Id","Correlation_Id","Start_Timestamp","End_Timestamp" +"RCCL_API","ncclGetVersion",1834151,1834151,416,18413845573432,18413845577374 +"RCCL_API","ncclGetUniqueId",1834151,1834151,1116,18413961300878,18413963267869 +"RCCL_API","ncclGetUniqueId",1834151,1834151,1481,18414166449182,18414166720831 +"RCCL_API","ncclGroupStart",1834151,1834151,1482,18414166723772,18414166726834 +"RCCL_API","ncclGroupEnd",1834151,1834151,1490,18414166823575,18414380520973 +"RCCL_API","ncclCommInitAll",1834151,1834151,1477,18414166402665,18414380522536 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89098,18414380660695,18414380661652 +"RCCL_API","ncclAllReduce",1834151,1834151,89097,18414380653860,18414380693574 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89108,18414380694631,18414380694659 +"RCCL_API","ncclAllReduce",1834151,1834151,89107,18414380694212,18414380704722 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89117,18414380706650,18414380706677 +"RCCL_API","ncclAllReduce",1834151,1834151,89116,18414380705574,18414380715055 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89126,18414380715749,18414380715774 +"RCCL_API","ncclAllReduce",1834151,1834151,89125,18414380715463,18414380723944 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89135,18414380724688,18414380724715 +"RCCL_API","ncclAllReduce",1834151,1834151,89134,18414380724395,18414380732209 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89154,18414380746383,18414380746411 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89157,18414380749863,18414380749889 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89160,18414380751671,18414380751696 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89163,18414380753326,18414380753353 +"RCCL_API","ncclCommGetAsyncError",1834151,1834151,89166,18414380755128,18414380755154 diff --git a/source/docs/data/rocprofv3_hip_memcpy_summary.png b/source/docs/data/rocprofv3_hip_memcpy_summary.png new file mode 100644 index 0000000000000000000000000000000000000000..c7b048a783ed0b7df5e8588dda9554d83cefe87f GIT binary patch literal 36263 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 bHy9AAw%wI0rvf8cfA5y6&W)UF_h0@$p-!t% literal 0 HcmV?d00001 diff --git a/source/docs/data/rocprofv3_memcpy_summary.png b/source/docs/data/rocprofv3_memcpy_summary.png new file mode 100644 index 0000000000000000000000000000000000000000..22f1f5134f2d8ff544a56ea2eca9277a7d978b1f GIT binary patch literal 11246 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 -- + rocprofv3 -- HIP trace +++++++++++ @@ -180,7 +180,7 @@ To trace HIP runtime APIs, use: .. code-block:: bash - rocprofv3 --hip-trace -- < app_relative_path > + rocprofv3 --hip-trace -- The above command generates a ``hip_api_trace.csv`` file prefixed with the process ID. @@ -199,7 +199,7 @@ To trace HIP compile time APIs, use: .. code-block:: shell - rocprofv3 --hip-compiler-trace -- < app_relative_path > + rocprofv3 --hip-compiler-trace -- The above command generates a ``hip_api_trace.csv`` file prefixed with the process ID. @@ -225,7 +225,7 @@ HSA trace contains the start and end time of HSA runtime API calls and their asy .. code-block:: bash - rocprofv3 --hsa-trace -- < app_relative_path > + rocprofv3 --hsa-trace -- The above command generates a ``hsa_api_trace.csv`` file prefixed with process ID. Note that the contents of this file have been truncated for demonstration purposes. @@ -291,7 +291,7 @@ To trace the API calls enclosed within the range, use: .. code-block:: bash - rocprofv3 --marker-trace -- < app_relative_path > + rocprofv3 --marker-trace -- Running the preceding command generates a ``marker_api_trace.csv`` file prefixed with the process ID. @@ -308,6 +308,74 @@ Here are the contents of ``marker_api_trace.csv`` file: For the description of the fields in the output file, see :ref:`output-file-fields`. +Kernel Rename +++++++++++++++ + +To rename kernels with their enclosing roctxRangePush/roctxRangePop message. Known as --roctx-rename in earlier rocprof versions. + +See how to use ``--kernel-rename`` option with help of below code snippet: + +.. code-block:: bash + + #include + + roctxRangePush("HIP_Kernel-1"); + + // Launching kernel from host + hipLaunchKernelGGL(matrixTranspose, dim3(WIDTH/THREADS_PER_BLOCK_X, WIDTH/THREADS_PER_BLOCK_Y), dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), 0,0,gpuTransposeMatrix,gpuMatrix, WIDTH); + + // Memory transfer from device to host + roctxRangePush("hipMemCpy-DeviceToHost"); + + hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost); + + roctxRangePop(); // for "hipMemcpy" + roctxRangePop(); // for "hipLaunchKernel" + roctxRangeStop(rangeId); + +To rename the kernel , use: + +.. code-block:: bash + + rocprofv3 --marker-trace --kernel-rename -- + +The above command generates a ``marker-trace`` file prefixed with the process ID. + +.. code-block:: shell + + $ cat 210_marker_api_trace.csv + "Domain","Function","Process_Id","Thread_Id","Correlation_Id","Start_Timestamp","End_Timestamp" + "MARKER_CORE_API","roctxGetThreadId",315155,315155,2,58378843928406,58378843930247 + "MARKER_CONTROL_API","roctxProfilerPause",315155,315155,3,58378844627184,58378844627502 + "MARKER_CONTROL_API","roctxProfilerResume",315155,315155,4,58378844638601,58378844639267 + "MARKER_CORE_API","pre-kernel-launch",315155,315155,5,58378844641787,58378844641787 + "MARKER_CORE_API","post-kernel-launch",315155,315155,6,58378844936586,58378844936586 + "MARKER_CORE_API","memCopyDth",315155,315155,7,58378844938371,58378851383270 + "MARKER_CORE_API","HIP_Kernel-1",315155,315155,1,58378526575735,58378851384485 + + +Kokkos Trace +++++++++++++++ + +rocprofv3 has a built-in `Kokkos Tools library `_ support to trace Kokkos API calls. `Kokkos `_ is a C++ library for writing performance portable applications. It is used in many scientific applications to write performance portable code that can run on CPUs, GPUs, and other accelerators. +rocprofv3 loads a built-in Kokkos tools library which emits roctx ranges with the labels passed through the API, e.g. Kokkos::parallel_for(“MyParallelForLabel”, …); will internally calls for roctxRangePush and enables the kernel renaming option so that the highly templated kernel names are replaced by the Kokkos labels. +To enable built-in marker support, use the ``kokkos-trace`` option. Internally this option enables ``marker-trace`` and ``kernel-rename``.: + +.. code-block:: bash + + rocprofv3 --kokkos-trace -- + +The above command generates a ``marker-trace`` file prefixed with the process ID. + +.. code-block:: shell + + $ cat 210_marker_api_trace.csv + "Domain","Function","Process_Id","Thread_Id","Correlation_Id","Start_Timestamp","End_Timestamp" + "MARKER_CORE_API","Kokkos::Initialization Complete",4069256,4069256,1,56728499773965,56728499773965 + "MARKER_CORE_API","Kokkos::Impl::CombinedFunctorReducer, CountFunctor, long int>::Reducer, void>",4069256,4069256,2,56728501756088,56728501764241 + "MARKER_CORE_API","Kokkos::parallel_reduce: fence due to result being value, not view",4069256,4069256,4,56728501767957,56728501769600 + "MARKER_CORE_API","Kokkos::Finalization Complete",4069256,4069256,6,56728502054554,56728502054554 + Kernel trace ++++++++++++++ @@ -315,7 +383,7 @@ To trace kernel dispatch traces, use: .. code-block:: shell - rocprofv3 --kernel-trace -- < app_relative_path > + rocprofv3 --kernel-trace -- The above command generates a ``kernel_trace.csv`` file prefixed with the process ID. @@ -339,7 +407,7 @@ To trace memory moves across the application, use: .. code-block:: shell - rocprofv3 –-memory-copy-trace -- < app_relative_path > + rocprofv3 –-memory-copy-trace -- The above command generates a ``memory_copy_trace.csv`` file prefixed with the process ID. @@ -372,7 +440,7 @@ memory operations (copies and scratch). .. code-block:: shell - rocprofv3 –-runtime-trace -- < app_relative_path > + rocprofv3 –-runtime-trace -- Running the above command generates ``hip_api_trace.csv``, ``kernel_trace.csv``, ``memory_copy_trace.csv``, ``scratch_memory_trace.csv``,and ``marker_api_trace.csv`` (if ``ROCTx`` APIs are specified in the application) files prefixed with the process ID. @@ -383,7 +451,7 @@ This is an all-inclusive option to collect all the above-mentioned traces. .. code-block:: shell - rocprofv3 –-sys-trace -- < app_relative_path > + rocprofv3 –-sys-trace -- Running the above command generates ``hip_api_trace.csv``, ``hsa_api_trace.csv``, ``kernel_trace.csv``, ``memory_copy_trace.csv``, and ``marker_api_trace.csv`` (if ``ROCTx`` APIs are specified in the application) files prefixed with the process ID. @@ -394,19 +462,45 @@ This option collects scratch memory operation's traces. Scratch is an address sp .. code-block:: shell - rocprofv3 --scratch-memory-trace -- < app_relative_path > + rocprofv3 --scratch-memory-trace -- -Stats -++++++++ + +RCCL trace +++++++++++++ + +`RCCL `_ (pronounced "Rickle") is a stand-alone library of standard collective communication routines for GPUs. This option traces those communication routines. + +.. code-block:: shell + + rocprofv3 --rccl-trace -- + +The above command generates a ``rccl_api_trace`` file prefixed with the process ID. + +.. code-block:: shell + + $ cat 197_rccl_api_trace.csv + +Here are the contents of ``rccl_api_trace.csv`` file: + +.. csv-table:: RCCL trace + :file: /data/rccl_trace.csv + :widths: 10,10,10,10,10,20,20 + :header-rows: 1 + +Post-processing tracing options +++++++++++++++++++++++++++++++++ + +1. Stats ++++++++++ This option collects statistics for the enabled tracing types. For example, to collect statistics of HIP APIs, when HIP trace is enabled. A higher percentage in statistics can help user focus on the API/function that has taken the most time: .. code-block:: shell - rocprofv3 --stats --hip-trace -- < app_relative_path > + rocprofv3 --stats --hip-trace -- -The above command generates a ``hip_api_stats.csv`` and ``hip_api_trace`` file prefixed with the process ID. +The above command generates a ``hip_api_stats.csv``, ``domain_stats.csv`` and ``hip_api_trace.csv`` file prefixed with the process ID. .. code-block:: shell @@ -419,8 +513,60 @@ Here are the contents of ``hip_api_stats.csv`` file: :widths: 10,10,20,20,10,10,10,10 :header-rows: 1 +Here are the contents of ``domain_stats.csv`` file: + +.. csv-table:: Domain stats + :file: /data/hip_domain_stats.csv + :widths: 10,10,20,20,10,10,10,10 + :header-rows: 1 + For the description of the fields in the output file, see :ref:`output-file-fields`. +2. Summary ++++++++++++ + +Output single summary of tracing data at the conclusion of the profiling session + +.. code-block:: shell + + rocprofv3 -S --hip-trace -- + +.. image:: /data/rocprofv3_summary.png + + +2.1 Summary per domain +++++++++++++++++++++++ + +Outputs the summary of each tracing domain at the end of profiling session. + +.. code-block:: shell + + rocprofv3 -D --hsa-trace --hip-trace -- + +The above command generates a ``hip_trace.csv``, ``hsa_trace.csv`` file prefixed with the process ID along with the summary of each domain at the terminal. + +2.2 Summary groups ++++++++++++++++++++ + +Users can create a summary of multiple domains by specifying the domain names in the command line. The summary groups are separated by a pipe (|) symbol. +To create a summary for ``MEMORY_COPY`` domains, use: + +.. code-block:: shell + + rocprofv3 --summary-groups MEMORY_COPY --sys-trace -- + +.. image:: /data/rocprofv3_memcpy_summary.png + + +To create a summary for ``MEMORY_COPY`` and ``HIP_API`` domains, use: + +.. code-block:: shell + + rocprofv3 --summary-groups 'MEMORY_COPY|HIP_API' --sys-trace -- + +.. image:: /data/rocprofv3_hip_memcpy_summary.png + + Kernel profiling ------------------- @@ -510,7 +656,7 @@ Properties { "jobs": [ { - "pmc": ["SQ_WAVES", "GRBM_COUNT", "GUI_ACTIVE"] + "pmc": ["SQ_WAVES", "GRBM_COUNT", "GRBM_GUI_ACTIVE"] }, { "pmc": ["FETCH_SIZE", "WRITE_SIZE"], @@ -534,7 +680,7 @@ Properties - pmc: - SQ_WAVES - GRBM_COUNT - - GUI_ACTIVE + - GRBM_GUI_ACTIVE - 'TCC_HIT[1]' - 'TCC_HIT[2]' - pmc: @@ -551,7 +697,7 @@ To supply the counters via ``command-line`` options, use: .. code-block:: shell - rocprofv3 --pmc SQ_WAVES GRBM_COUNT GRBM_GUI_ACTIVE -- + rocprofv3 --pmc SQ_WAVES GRBM_COUNT GRBM_GUI_ACTIVE -- .. note:: 1. Please note that more than 1 counters should be separated by a space or a comma. @@ -564,7 +710,7 @@ To supply the input file for kernel profiling, use: .. code-block:: shell - rocprofv3 -i input.txt -- + rocprofv3 -i input.txt -- Running the above command generates a ``./pmc_n/counter_collection.csv`` file prefixed with the process ID. For each ``pmc`` row, a directory ``pmc_n`` containing a ``counter_collection.csv`` file is generated, where n = 1 for the first row and so on. @@ -636,7 +782,7 @@ To collect counters for the kernels matching the filters specified in the preced .. code-block:: shell - rocprofv3 -i input.yml -- + rocprofv3 -i input.yml -- $ cat pass_1/312_counter_collection.csv "Correlation_Id","Dispatch_Id","Agent_Id","Queue_Id","Process_Id","Thread_Id","Grid_Size","Kernel_Name","Workgroup_Size","LDS_Block_Size","Scratch_Size","VGPR_Count","SGPR_Count","Counter_Name","Counter_Value","Start_Timestamp","End_Timestamp" diff --git a/source/docs/rocprofiler-sdk.dox.in b/source/docs/rocprofiler-sdk.dox.in index 7188a97c..e8fdd760 100644 --- a/source/docs/rocprofiler-sdk.dox.in +++ b/source/docs/rocprofiler-sdk.dox.in @@ -139,7 +139,8 @@ FILE_PATTERNS = *.h \ *.tcc \ conf.py RECURSIVE = YES -EXCLUDE = +EXCLUDE = @SOURCE_DIR@/README.md \ + @SOURCE_DIR@/include/rocprofiler-sdk/rccl/details/rccl.h EXCLUDE_SYMLINKS = YES EXCLUDE_PATTERNS = */.git/* \ @SOURCE_DIR@/**/tests/* \ @@ -266,7 +267,7 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex LATEX_MAKEINDEX_CMD = makeindex COMPACT_LATEX = NO -PAPER_TYPE = +PAPER_TYPE = a4 EXTRA_PACKAGES = float LATEX_HEADER = LATEX_FOOTER = @@ -332,7 +333,8 @@ MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = NO INCLUDE_PATH = @SOURCE_DIR@/source/include -INCLUDE_FILE_PATTERNS = *.h +INCLUDE_FILE_PATTERNS = *.h \ + *.hpp PREDEFINED = "ROCPROFILER_API=" \ "ROCPROFILER_EXPORT=" \ "ROCPROFILER_IMPORT=" \ diff --git a/source/include/rocprofiler-sdk/rccl/details/rccl.h b/source/include/rocprofiler-sdk/rccl/details/rccl.h index 304f6025..e114a26d 100644 --- a/source/include/rocprofiler-sdk/rccl/details/rccl.h +++ b/source/include/rocprofiler-sdk/rccl/details/rccl.h @@ -47,7 +47,7 @@ typedef struct } ncclUniqueId; /*! @defgroup rccl_result_code Result Codes - @details The various result codes that RCCL API calls may return + @brief The various result codes that RCCL API calls may return @{ */ /*! @brief Result type @@ -71,12 +71,14 @@ typedef enum #define NCCL_SPLIT_NOCOLOR -1 /*! @defgroup rccl_config_type Communicator Configuration - @details Structure that allows for customizing Communicator behavior via + @brief Structure that allows for customizing Communicator behavior via ncclCommInitRankConfig @{ */ -/*! @brief Communicator configuration - @details Users can assign value to attributes to specify the behavior of a communicator */ +/** + * @defgroup Communicator configuration + * @brief Users can assign value to attributes to specify the behavior of a communicator. + */ typedef struct ncclConfig_v21700 { /* attributes that users should never touch. */ @@ -122,7 +124,7 @@ ncclResult_t pncclMemFree(void* ptr); /*! @defgroup rccl_api_version Version Information - @details API call that returns RCCL version + @brief API call that returns RCCL version @{ */ /*! @brief Return the RCCL_VERSION_CODE of RCCL in the supplied integer. @@ -140,7 +142,7 @@ pncclGetVersion(int* version); /*! @} */ /*! @defgroup rccl_api_communicator Communicator Initialization/Destruction - @details API calls that operate on communicators. + @brief API calls that operate on communicators. Communicators objects are used to launch collective communication operations. Unique ranks between 0 and N-1 must be assigned to each HIP device participating in the same Communicator. @@ -292,7 +294,7 @@ pncclCommSplit(ncclComm_t comm, int color, int key, ncclComm_t* newcomm, ncclCon /*! @} */ /*! @defgroup rccl_api_errcheck Error Checking Calls - @details API calls that check for errors + @brief API calls that check for errors @{ */ /*! @brief Returns a string for each result code. @@ -330,7 +332,7 @@ pncclCommGetAsyncError(ncclComm_t comm, ncclResult_t* asyncError); /*! @} */ /*! @defgroup rccl_api_comminfo Communicator Information - @details API calls that query communicator information + @brief API calls that query communicator information @{ */ /*! @brief Gets the number of ranks in the communicator clique. @@ -391,7 +393,7 @@ pncclCommDeregister(const ncclComm_t comm, void* handle); /*! @endcond */ /*! @defgroup rccl_api_enumerations API Enumerations - @details Enumerations used by collective communication calls + @brief Enumerations used by collective communication calls @{ */ /*! @brief Dummy reduction enumeration @@ -454,7 +456,7 @@ typedef enum /*! @} */ /*! @defgroup rccl_api_custom_redop Custom Reduction Operator - @details API calls relating to creation/destroying custom reduction operator + @brief API calls relating to creation/destroying custom reduction operator that pre-multiplies local source arrays prior to reduction @{ */ @@ -516,7 +518,7 @@ pncclRedOpDestroy(ncclRedOp_t op, ncclComm_t comm); /*! @} */ /*! @defgroup rccl_collective_api Collective Communication Operations - @details Collective communication operations must be called separately for each + @brief Collective communication operations must be called separately for each communicator in a communicator clique. They return when operations have been enqueued on the HIP stream. @@ -935,7 +937,7 @@ pncclAllToAllv(const void* sendbuff, /*! @} */ /*! @defgroup msccl_api MSCCL Algorithm - @details API calls relating to the optional MSCCL algorithm datapath + @brief API calls relating to the optional MSCCL algorithm datapath @{ */ /*! @brief Opaque handle to MSCCL algorithm */ @@ -1030,7 +1032,7 @@ pmscclUnloadAlgo(mscclAlgoHandle_t mscclAlgoHandle); /*! @} */ /*! @defgroup rccl_group_api Group semantics - @details When managing multiple GPUs from a single thread, and since RCCL collective + @brief When managing multiple GPUs from a single thread, and since RCCL collective calls may perform inter-CPU synchronization, we need to "group" calls for different ranks/devices into a single call. diff --git a/source/include/rocprofiler-sdk/registration.h b/source/include/rocprofiler-sdk/registration.h index 837367af..a1a8f813 100644 --- a/source/include/rocprofiler-sdk/registration.h +++ b/source/include/rocprofiler-sdk/registration.h @@ -30,7 +30,7 @@ ROCPROFILER_EXTERN_C_INIT /** * @defgroup REGISTRATION_GROUP Tool registration * - * Data types and functions for tool registration with rocprofiler + * @brief Data types and functions for tool registration with rocprofiler * @{ */ diff --git a/source/include/rocprofiler-sdk/rocprofiler.h b/source/include/rocprofiler-sdk/rocprofiler.h index 1681cef9..d2b5a632 100644 --- a/source/include/rocprofiler-sdk/rocprofiler.h +++ b/source/include/rocprofiler-sdk/rocprofiler.h @@ -86,7 +86,7 @@ ROCPROFILER_EXTERN_C_INIT /** * @defgroup MISCELLANEOUS_GROUP Miscellaneous Utility Functions - * + * @brief utility functions for library * @{ */ From 25049c19823ab40f53fa39af0a8fdd805f1463f5 Mon Sep 17 00:00:00 2001 From: "Bhardwaj, Gopesh" Date: Thu, 5 Dec 2024 19:47:57 +0530 Subject: [PATCH 2/2] updating roctx documentation for functions (#30) updating roctx documentation for funcitons (cherry picked from commit 6d2e70d8da3f984934a0086ff98d3053ab21a0dc) --- source/docs/how-to/using-rocprofv3.rst | 61 ++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/source/docs/how-to/using-rocprofv3.rst b/source/docs/how-to/using-rocprofv3.rst index add8dc36..17502244 100644 --- a/source/docs/how-to/using-rocprofv3.rst +++ b/source/docs/how-to/using-rocprofv3.rst @@ -256,6 +256,14 @@ Here is a list of useful APIs for code instrumentation. - ``roctxRangePush``: Starts a new nested range. - ``roctxRangePop``: Stops the current nested range. - ``roctxRangeStop``: Stops the given range. +- ``roctxProfilerPause``: Request any currently running profiling tool that it should stop collecting data. +- ``roctxProfilerResume``: Request any currently running profiling tool that it should resume collecting data. +- ``roctxGetThreadId``: Retrieve a id value for the current thread which will be identical to the id value a profiling tool gets via `rocprofiler_get_thread_id(rocprofiler_thread_id_t*)`. +- ``roctxNameOsThread``: Current CPU OS thread to be labeled by the provided name in the output of the profiling tool. +- ``roctxNameHsaAgent``: Given HSA agent to be labeled by the provided name in the output of the profiling tool. +- ``roctxNameHipDevice``: Given HIP device id to be labeled by the provided name in the output of the profiling tool. +- ``roctxNameHipStream``: Given HIP stream to be labeled by the provided name in the output of the profiling tool. + .. note:: To use ``rocprofv3`` for marker tracing, including and linking to old ROCTx works but it is recommended to switch to new ROCTx because @@ -308,6 +316,59 @@ Here are the contents of ``marker_api_trace.csv`` file: For the description of the fields in the output file, see :ref:`output-file-fields`. +``roctxProfilerPause`` and ``roctxProfilerResume`` can be used to hide the calls between them. This is useful when you want to hide the calls that are not relevant to your profiling session. + +.. code-block:: bash + + #include + + // Memory transfer from host to device + HIP_API_CALL(hipMemcpy(gpuMatrix, Matrix, NUM * sizeof(float), hipMemcpyHostToDevice)); + + auto tid = roctx_thread_id_t{}; + roctxGetThreadId(&tid); + roctxProfilerPause(tid); + // Memory transfer that should be hidden by profiling tool + HIP_API_CALL( + hipMemcpy(gpuTransposeMatrix, gpuMatrix, NUM * sizeof(float), hipMemcpyDeviceToDevice)); + roctxProfilerResume(tid); + + // Lauching kernel from host + hipLaunchKernelGGL(matrixTranspose, + dim3(WIDTH / THREADS_PER_BLOCK_X, WIDTH / THREADS_PER_BLOCK_Y), + dim3(THREADS_PER_BLOCK_X, THREADS_PER_BLOCK_Y), + 0, + 0, + gpuTransposeMatrix, + gpuMatrix, + WIDTH); + + // Memory transfer from device to host + HIP_API_CALL( + hipMemcpy(TransposeMatrix, gpuTransposeMatrix, NUM * sizeof(float), hipMemcpyDeviceToHost)); + +.. code-block:: shell + + rocprofv3 --marker-trace --hip-trace -- + + The above command generates a ``hip_api_trace.csv`` file prefixed with the process ID, which has only 2 `hipMemcpy` calls and the in between ``hipMemcpyDeviceToHost`` is hidden . + +.. code-block:: shell + + "Domain","Function","Process_Id","Thread_Id","Correlation_Id","Start_Timestamp","End_Timestamp" + "HIP_COMPILER_API","__hipRegisterFatBinary",1643920,1643920,1,320301257609216,320301257636427 + "HIP_COMPILER_API","__hipRegisterFunction",1643920,1643920,2,320301257650707,320301257678857 + "HIP_RUNTIME_API","hipGetDevicePropertiesR0600",1643920,1643920,4,320301258114239,320301337764472 + "HIP_RUNTIME_API","hipMalloc",1643920,1643920,5,320301338073823,320301338247374 + "HIP_RUNTIME_API","hipMalloc",1643920,1643920,6,320301338248284,320301338399595 + "HIP_RUNTIME_API","hipMemcpy",1643920,1643920,7,320301338410995,320301631549262 + "HIP_COMPILER_API","__hipPushCallConfiguration",1643920,1643920,10,320301632131175,320301632134215 + "HIP_COMPILER_API","__hipPopCallConfiguration",1643920,1643920,11,320301632137745,320301632139735 + "HIP_RUNTIME_API","hipLaunchKernel",1643920,1643920,12,320301632142615,320301632898289 + "HIP_RUNTIME_API","hipMemcpy",1643920,1643920,14,320301632901249,320301633934395 + "HIP_RUNTIME_API","hipFree",1643920,1643920,15,320301643320908,320301643511479 + "HIP_RUNTIME_API","hipFree",1643920,1643920,16,320301643512629,320301643585639 + Kernel Rename ++++++++++++++