From 7afedc63be9a87ec7284ef0270d93bb2d0d24358 Mon Sep 17 00:00:00 2001 From: "Madsen, Jonathan" Date: Fri, 30 May 2025 00:13:19 -0500 Subject: [PATCH] [rocprofv3] SQLite3 database output (rocpd) support + rocprofiler-sdk-rocpd (#403) * [rocprofv3] rocpd SQLite3 database output support * Move counters xml and yaml to source/share/rocprofiler-sdk - more representative of install hierarchy * Add share/rocprofiler-sdk/rocpd SQL files * Experimental rocprofiler-sdk SQL API * rocprofv3 default output format is rocpd * Fix rocpd event ids for counter collection w/o kernel dispatch * Remove fktable entries from rocpd_tables.sql * Fix rocpd schema path * Fix install component for roctx python bindings * rocprofiler-sdk-rocpd - create include/rocprofiler-sdk-rocpd - create rocprofiler-sdk-rocpd library, package, etc. - default all "guid" fields to "{{guid}}" in tables - remove "{{view_uuid}}" support (always unused) * Migrate rocprofv3 to use rocprofiler-sdk-rocpd * Fix missing foreign key reference * Revert change * Fix cmake comment * Fix maybe-uninitialized compiler warning * Fix maybe-uninitialized compiler warning * Add logging to rocpd_sql_load_schema * Improve string sanitization when inserting json strings * Initialize rocpd logging on rocprofiler-sdk-rocpd library load * Revert lib/output/generatePerfetto.cpp changes * [temporary] Tweak rocprofv3-test-list-avail-trace-execute test log level * Update get_install_path for lib/rocprofiler-sdk-rocpd/sql.cpp - try to resolve issues on RHEL/SLES for dladdr * Update lib/common/logging.cpp - enable environ overrides * dlsym for rocpd_sql_load_schema * Make dl_info.dli_fname lexically normal * Implement node_info alternatives if /etc/machine-id does not exist * Misc include fixes * SHA256 and UUIDv7 support * Implement UUIDv7 in generateRocpd.cpp * Support push/pop environment variables * Minor tweak * Fix glog segfaults when unsetting glog env * Updated CHANGELOG * Updates tests/pytest-packages - rocpd_reader.py: RocpdReader * Update tests / marker_views.sql - add test_rocpd_data * Update rocpd_tables.sql - Use AUTOINCREMENT - insert "uuid" and "guid" into rocpd_metadata * Minor updates to generateRocpd.cpp - don't quote GUID - use sqlite3_open_v2 - use sqlite3_close_v2 * Update execute_raw_sql_statements_impl - uses sqlite3_last_insert_rowid for autoincrement * Update SQL deferred_transaction - CI check for nullptr to connection * Apply suggestions from code review Co-authored-by: Welton, Benjamin * Code review updates - formatting - replace if with switch - remove loop for {{uuid}} * Fix pmc_groups handling in rocprofv3 * Address code review feedback - Include rocm_version in rocprofv3 version info - Note `--version` option for `rocprofv3` in CHANGELOG.md - remove commented out code * Fix packaging dependencies * Fix install package step of CI workflow * Fix install package step of CI workflow --------- Co-authored-by: Jonathan R. Madsen Co-authored-by: Welton, Benjamin --- .github/workflows/continuous_integration.yml | 6 +- CHANGELOG.md | 8 + CMakeLists.txt | 3 +- .../build-config.cmake.in | 9 + .../rocprofiler-sdk-rocpd/config.cmake.in | 73 + cmake/Templates/setup-env.sh.in | 27 +- cmake/rocprofiler_config_install_rocpd.cmake | 106 ++ cmake/rocprofiler_config_packaging.cmake | 18 +- external/CMakeLists.txt | 8 +- source/bin/CMakeLists.txt | 3 +- source/bin/rocprofv3.py | 60 +- source/include/CMakeLists.txt | 1 + .../rocprofiler-sdk-rocpd/CMakeLists.txt | 18 + .../include/rocprofiler-sdk-rocpd/defines.h | 130 ++ source/include/rocprofiler-sdk-rocpd/rocpd.h | 118 ++ source/include/rocprofiler-sdk-rocpd/sql.h | 151 ++ source/include/rocprofiler-sdk-rocpd/types.h | 81 + .../rocprofiler-sdk-rocpd/version.h.in | 115 ++ .../cxx/serialization/save.hpp | 1 - source/lib/CMakeLists.txt | 7 +- source/lib/common/CMakeLists.txt | 8 +- source/lib/common/environment.cpp | 51 + source/lib/common/environment.hpp | 46 +- source/lib/common/logging.cpp | 53 +- source/lib/common/logging.hpp | 2 +- source/lib/common/sha256.cpp | 229 +++ source/lib/common/sha256.hpp | 81 + source/lib/common/uuid_v7.cpp | 151 ++ source/lib/common/uuid_v7.hpp | 49 + source/lib/output/CMakeLists.txt | 8 + source/lib/output/generateRocpd.cpp | 1398 +++++++++++++++++ source/lib/output/generateRocpd.hpp | 76 + source/lib/output/metadata.cpp | 63 +- source/lib/output/metadata.hpp | 30 + source/lib/output/node_info.cpp | 121 +- source/lib/output/node_info.hpp | 1 - source/lib/output/output_config.cpp | 3 +- source/lib/output/output_config.hpp | 2 + source/lib/output/sql/CMakeLists.txt | 8 + source/lib/output/sql/common.cpp | 205 +++ source/lib/output/sql/common.hpp | 129 ++ .../lib/output/sql/deferred_transaction.cpp | 62 + .../lib/output/sql/deferred_transaction.hpp | 45 + source/lib/output/sql/extract_data_type.hpp | 141 ++ source/lib/python/utilities.cmake | 4 +- .../lib/rocprofiler-sdk-rocpd/CMakeLists.txt | 46 + source/lib/rocprofiler-sdk-rocpd/rocpd.cpp | 117 ++ source/lib/rocprofiler-sdk-rocpd/sql.cpp | 247 +++ .../rocprofv3-multi-node.md | 335 ---- source/lib/rocprofiler-sdk-tool/tool.cpp | 19 + .../rocprofiler-sdk/counters/CMakeLists.txt | 2 - .../counters/xml/CMakeLists.txt | 10 - .../counters/yaml/CMakeLists.txt | 6 - source/lib/tests/common/CMakeLists.txt | 10 +- source/lib/tests/common/environment.cpp | 45 + source/lib/tests/common/sha256.cpp | 57 + source/lib/tests/common/uuid_v7.cpp | 80 + source/scripts/generate-rocpd.py | 533 ------- source/share/CMakeLists.txt | 5 + .../rocprofiler-sdk-rocpd/CMakeLists.txt | 15 + .../rocprofiler-sdk-rocpd/data_views.sql | 929 +++++++++++ .../rocprofiler-sdk-rocpd/marker_views.sql | 218 +++ .../rocprofiler-sdk-rocpd/rocpd_indexes.sql | 27 + .../rocprofiler-sdk-rocpd/rocpd_tables.sql | 373 +++++ .../rocprofiler-sdk-rocpd/rocpd_views.sql | 139 ++ .../rocprofiler-sdk-rocpd/summary_views.sql | 1389 ++++++++++++++++ source/share/rocprofiler-sdk/CMakeLists.txt | 32 +- .../rocprofiler-sdk}/basic_counters.xml | 0 .../rocprofiler-sdk}/counter_defs.yaml | 0 .../rocprofiler-sdk}/derived_counters.xml | 0 tests/pytest-packages/CMakeLists.txt | 3 +- .../pytest_utils/rocpd_reader.py | 37 + tests/pytest-packages/tests/rocprofv3.py | 77 + .../counter-collection/input3/CMakeLists.txt | 4 +- .../list_metrics/CMakeLists.txt | 4 +- .../multiplex/CMakeLists.txt | 4 +- tests/rocprofv3/tracing/CMakeLists.txt | 20 +- tests/rocprofv3/tracing/conftest.py | 12 + tests/rocprofv3/tracing/input_systrace.json | 3 +- tests/rocprofv3/tracing/input_trace.json | 3 +- tests/rocprofv3/tracing/validate.py | 8 + 81 files changed, 7725 insertions(+), 993 deletions(-) create mode 100644 cmake/Templates/rocprofiler-sdk-rocpd/build-config.cmake.in create mode 100644 cmake/Templates/rocprofiler-sdk-rocpd/config.cmake.in create mode 100644 cmake/rocprofiler_config_install_rocpd.cmake create mode 100644 source/include/rocprofiler-sdk-rocpd/CMakeLists.txt create mode 100644 source/include/rocprofiler-sdk-rocpd/defines.h create mode 100644 source/include/rocprofiler-sdk-rocpd/rocpd.h create mode 100644 source/include/rocprofiler-sdk-rocpd/sql.h create mode 100644 source/include/rocprofiler-sdk-rocpd/types.h create mode 100644 source/include/rocprofiler-sdk-rocpd/version.h.in create mode 100644 source/lib/common/sha256.cpp create mode 100644 source/lib/common/sha256.hpp create mode 100644 source/lib/common/uuid_v7.cpp create mode 100644 source/lib/common/uuid_v7.hpp create mode 100644 source/lib/output/generateRocpd.cpp create mode 100644 source/lib/output/generateRocpd.hpp create mode 100644 source/lib/output/sql/CMakeLists.txt create mode 100644 source/lib/output/sql/common.cpp create mode 100644 source/lib/output/sql/common.hpp create mode 100644 source/lib/output/sql/deferred_transaction.cpp create mode 100644 source/lib/output/sql/deferred_transaction.hpp create mode 100644 source/lib/output/sql/extract_data_type.hpp create mode 100644 source/lib/rocprofiler-sdk-rocpd/CMakeLists.txt create mode 100644 source/lib/rocprofiler-sdk-rocpd/rocpd.cpp create mode 100644 source/lib/rocprofiler-sdk-rocpd/sql.cpp delete mode 100644 source/lib/rocprofiler-sdk-tool/rocprofv3-multi-node.md delete mode 100644 source/lib/rocprofiler-sdk/counters/xml/CMakeLists.txt delete mode 100644 source/lib/rocprofiler-sdk/counters/yaml/CMakeLists.txt create mode 100644 source/lib/tests/common/sha256.cpp create mode 100644 source/lib/tests/common/uuid_v7.cpp delete mode 100755 source/scripts/generate-rocpd.py create mode 100644 source/share/rocprofiler-sdk-rocpd/CMakeLists.txt create mode 100644 source/share/rocprofiler-sdk-rocpd/data_views.sql create mode 100644 source/share/rocprofiler-sdk-rocpd/marker_views.sql create mode 100644 source/share/rocprofiler-sdk-rocpd/rocpd_indexes.sql create mode 100644 source/share/rocprofiler-sdk-rocpd/rocpd_tables.sql create mode 100644 source/share/rocprofiler-sdk-rocpd/rocpd_views.sql create mode 100644 source/share/rocprofiler-sdk-rocpd/summary_views.sql rename source/{lib/rocprofiler-sdk/counters/xml => share/rocprofiler-sdk}/basic_counters.xml (100%) mode change 100755 => 100644 rename source/{lib/rocprofiler-sdk/counters/yaml => share/rocprofiler-sdk}/counter_defs.yaml (100%) rename source/{lib/rocprofiler-sdk/counters/xml => share/rocprofiler-sdk}/derived_counters.xml (100%) mode change 100755 => 100644 create mode 100644 tests/pytest-packages/pytest_utils/rocpd_reader.py diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index ace70fd5db..063e89bc34 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -146,7 +146,8 @@ jobs: ls -la ls -la ./build dpkg -i ./build/rocprofiler-sdk-roctx_*.deb - for i in $(ls -S ./build/rocprofiler-sdk*.deb | egrep -v roctx); do dpkg -i ${i}; done; + dpkg -i ./build/rocprofiler-sdk-rocpd_*.deb + for i in $(ls -S ./build/rocprofiler-sdk*.deb | egrep -v 'roctx|rocpd'); do dpkg -i ${i}; done; - name: Test Installed Packages if: ${{ contains(matrix.runner, env.CORE_EXT_RUNNER) }} @@ -271,7 +272,8 @@ jobs: ls -la ls -la ./build dpkg -i ./build/rocprofiler-sdk-roctx_*.deb - for i in $(ls -S ./build/rocprofiler-sdk*.deb | egrep -v roctx); do dpkg -i ${i}; done; + dpkg -i ./build/rocprofiler-sdk-rocpd_*.deb + for i in $(ls -S ./build/rocprofiler-sdk*.deb | egrep -v 'roctx|rocpd'); do dpkg -i ${i}; done; - name: Test Installed Packages if: ${{ contains(matrix.runner, env.CORE_EXT_RUNNER) }} diff --git a/CHANGELOG.md b/CHANGELOG.md index e0f61b2378..6c4036e94d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -176,12 +176,20 @@ Full documentation for ROCprofiler-SDK is available at [rocm.docs.amd.com/projec - type-relative == logical_node_type_id - Added MI300 stochastic (hardware-based) PC sampling support in ROCProfiler-SDK and ROCProfV3 - Python bindings for rocprofiler-sdk-roctx +- SQLite3 output support for rocprofv3 (`--output-format rocpd`) +- Added `rocprofiler-sdk-rocpd` package + - public API in `include/rocprofiler-sdk-rocpd/rocpd.h` + - library implementation in `librocprofiler-sdk-rocpd.so` + - support for `find_package(rocprofiler-sdk-rocpd)` + - `rocprofiler-sdk-rocpd` DEB and RPM packages +- Support `--version` option for `rocprofv3` ### Changed - SDK no longer creates a background thread when every tool returns a nullptr from `rocprofiler_configure`. - Updated disassembly.hpp's vaddr-to-file-offset mapping to use the dedicated comgr API. - rocprofv3 shorthand argument for `--collection-period` is now `-P` (upper-case) as `-p` (lower-case) is reserved for later use +- default output format for rocprofv3 is now `rocpd` (SQLite3 database) ### Resolved issues diff --git a/CMakeLists.txt b/CMakeLists.txt index bc1daaf1eb..65dd7f4d30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ mark_as_advanced(CMAKE_INSTALL_RPATH_USE_LINK_PATH CMAKE_DEBUG_POSTFIX) set(ROCPROFILER_INTERNAL_BUILD_DOCS OFF - CACHE INTERNAL "Generates rocprofiler/version.h and exits (no build targets)") + CACHE INTERNAL "Generates rocprofiler-sdk/version.h and exits (no build targets)") if(ROCPROFILER_INTERNAL_BUILD_DOCS) add_subdirectory(source/include) return() @@ -114,6 +114,7 @@ add_subdirectory(source) include(rocprofiler_config_install) include(rocprofiler_config_install_roctx) +include(rocprofiler_config_install_rocpd) if(ROCPROFILER_BUILD_TESTS) add_subdirectory(tests) diff --git a/cmake/Templates/rocprofiler-sdk-rocpd/build-config.cmake.in b/cmake/Templates/rocprofiler-sdk-rocpd/build-config.cmake.in new file mode 100644 index 0000000000..a914160cb4 --- /dev/null +++ b/cmake/Templates/rocprofiler-sdk-rocpd/build-config.cmake.in @@ -0,0 +1,9 @@ +# Config file for @PACKAGE_NAME@ and its component libraries in the build tree +# + +list(APPEND @PACKAGE_NAME@_INCLUDE_DIR @CMAKE_BINARY_DIR@/source/include) + +foreach(COMP @PROJECT_BUILD_TREE_TARGETS@) + list(APPEND @PACKAGE_NAME@_LIBRARIES ${COMP}) + target_link_libraries(@PACKAGE_NAME@::@PACKAGE_NAME@ INTERFACE ${COMP}) +endforeach() diff --git a/cmake/Templates/rocprofiler-sdk-rocpd/config.cmake.in b/cmake/Templates/rocprofiler-sdk-rocpd/config.cmake.in new file mode 100644 index 0000000000..f12f3647cf --- /dev/null +++ b/cmake/Templates/rocprofiler-sdk-rocpd/config.cmake.in @@ -0,0 +1,73 @@ +# - Config file for @PACKAGE_NAME@ and its component libraries +# It defines the following variables: +# +# @PACKAGE_NAME@_VERSION +# @PACKAGE_NAME@_INCLUDE_DIR +# @PACKAGE_NAME@_LIB_DIR +# @PACKAGE_NAME@_LIBRARIES +# +# It provides the following interface libraries: +# +# @PACKAGE_NAME@::@PACKAGE_NAME@ +# + +# prevent "target already exists" error +include_guard(DIRECTORY) + +# compute paths +get_filename_component(@PACKAGE_NAME@_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + +@PACKAGE_INIT@ + +set_and_check(@PACKAGE_NAME@_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") +set_and_check(@PACKAGE_NAME@_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@") +get_filename_component(@PACKAGE_NAME@_ROOT_DIR ${@PACKAGE_NAME@_INCLUDE_DIR} PATH) +set_and_check(@PACKAGE_NAME@_ROOT "${@PACKAGE_NAME@_ROOT_DIR}") + +# extra validation +foreach(_@PACKAGE_NAME@_SUBDIR @PROJECT_EXTRA_DIRS@) + set_and_check(_@PACKAGE_NAME@_SUBDIR_CHECK + "${PACKAGE_PREFIX_DIR}/${_@PACKAGE_NAME@_SUBDIR}") + unset(_@PACKAGE_NAME@_SUBDIR_CHECK) +endforeach() + +set(@PACKAGE_NAME@_LIBRARIES) + +# add interface library +add_library(@PACKAGE_NAME@::@PACKAGE_NAME@ INTERFACE IMPORTED) + +if(@PACKAGE_NAME@_BUILD_TREE + AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/@PACKAGE_NAME@-build-config.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@PACKAGE_NAME@-build-config.cmake") +else() + include("${@PACKAGE_NAME@_CMAKE_DIR}/@PACKAGE_NAME@-targets.cmake") + + # Library dependencies + if(@PACKAGE_NAME@_FIND_COMPONENTS) + foreach(COMP ${@PACKAGE_NAME@_FIND_COMPONENTS}) + set(TARG @PACKAGE_NAME@::@PACKAGE_NAME@-${COMP}) + if(TARGET ${TARG}) + set(@PACKAGE_NAME@_${COMP}_FOUND 1) + list(APPEND @PACKAGE_NAME@_LIBRARIES ${TARG}) + target_link_libraries(@PACKAGE_NAME@::@PACKAGE_NAME@ INTERFACE ${TARG}) + else() + set(@PACKAGE_NAME@_${COMP}_FOUND 0) + endif() + endforeach() + else() + foreach(TARG @PROJECT_BUILD_TARGETS@) + set(TARG @PACKAGE_NAME@::${TARG}) + list(APPEND @PACKAGE_NAME@_LIBRARIES ${TARG}) + target_link_libraries(@PACKAGE_NAME@::@PACKAGE_NAME@ INTERFACE ${TARG}) + endforeach() + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + @PACKAGE_NAME@ + FOUND_VAR @PACKAGE_NAME@_FOUND + VERSION_VAR @PACKAGE_NAME@_VERSION + REQUIRED_VARS @PACKAGE_NAME@_ROOT_DIR @PACKAGE_NAME@_INCLUDE_DIR + @PACKAGE_NAME@_LIB_DIR @PACKAGE_NAME@_LIBRARIES @PACKAGE_NAME@_VERSION + HANDLE_COMPONENTS HANDLE_VERSION_RANGE) diff --git a/cmake/Templates/setup-env.sh.in b/cmake/Templates/setup-env.sh.in index 1fb07a33fa..7c64413a28 100644 --- a/cmake/Templates/setup-env.sh.in +++ b/cmake/Templates/setup-env.sh.in @@ -8,16 +8,35 @@ if [ ! -d "${BASEDIR}" ]; then return 1 fi +@PACKAGE_NAME_UNDERSCORED@_get_python3_path() +{ + local PYTHON3_EXECUTABLE=$(command -v python3 2> /dev/null) + if [ -n "${PYTHON3_EXECUTABLE}" ]; then + local PYTHON3_VERSION=$(${PYTHON3_EXECUTABLE} -c "import sys; print(f'{sys.version_info[0]}.{sys.version_info[1]}')" 2> /dev/null) + local @PACKAGE_NAME_UNDERSCORED@_PYTHONPATH=${BASEDIR}/@CMAKE_INSTALL_LIBDIR@/python${PYTHON3_VERSION}/site-packages + if [ -d "${@PACKAGE_NAME_UNDERSCORED@_PYTHONPATH}" ]; then + echo ${BASEDIR}/@CMAKE_INSTALL_LIBDIR@/python${PYTHON3_VERSION}/site-packages + fi + fi +} + @PACKAGE_NAME_UNDERSCORED@_ROOT=${BASEDIR} +@PACKAGE_NAME_UNDERSCORED@_DIR=${BASEDIR}/@CMAKE_INSTALL_LIBDIR@/cmake/@PACKAGE_NAME@ PATH=${BASEDIR}/bin:${PATH} LD_LIBRARY_PATH=${BASEDIR}/@CMAKE_INSTALL_LIBDIR@:${LD_LIBRARY_PATH} -PYTHONPATH=${BASEDIR}/@CMAKE_INSTALL_PYTHONDIR@:${PYTHONPATH} CMAKE_PREFIX_PATH=${BASEDIR}:${CMAKE_PREFIX_PATH} -@PACKAGE_NAME_UNDERSCORED@_DIR=${BASEDIR}/@CMAKE_INSTALL_LIBDIR@/cmake/@PACKAGE_NAME@ + +if [ -z "@CMAKE_INSTALL_PYTHONDIR@" ]; then + PYTHONPATH=$(@PACKAGE_NAME_UNDERSCORED@_get_python3_path):${PYTHONPATH} +else + PYTHONPATH=${BASEDIR}/@CMAKE_INSTALL_PYTHONDIR@:${PYTHONPATH} +fi + +unset @PACKAGE_NAME_UNDERSCORED@_get_python3_path export @PACKAGE_NAME_UNDERSCORED@_ROOT +export @PACKAGE_NAME_UNDERSCORED@_DIR export PATH export LD_LIBRARY_PATH -export PYTHONPATH export CMAKE_PREFIX_PATH -export @PACKAGE_NAME_UNDERSCORED@_DIR +export PYTHONPATH diff --git a/cmake/rocprofiler_config_install_rocpd.cmake b/cmake/rocprofiler_config_install_rocpd.cmake new file mode 100644 index 0000000000..f67abd120f --- /dev/null +++ b/cmake/rocprofiler_config_install_rocpd.cmake @@ -0,0 +1,106 @@ +# include guard +include_guard(GLOBAL) + +include(CMakePackageConfigHelpers) + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME rocpd) +set(SDK_PACKAGE_NAME "${PROJECT_NAME}") +set(PACKAGE_NAME "${PROJECT_NAME}-rocpd") + +install( + EXPORT ${PACKAGE_NAME}-targets + FILE ${PACKAGE_NAME}-targets.cmake + NAMESPACE ${PACKAGE_NAME}:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} + COMPONENT rocpd) + +rocprofiler_install_env_setup_files( + NAME ${PACKAGE_NAME} + VERSION ${PROJECT_VERSION} + INSTALL_DIR ${CMAKE_INSTALL_DATAROOTDIR} + COMPONENT rocpd) + +# ------------------------------------------------------------------------------# +# install tree +# +set(PROJECT_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}) +set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) +set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) +set(PROJECT_BUILD_TARGETS ${PACKAGE_NAME}-shared-library) +set(PROJECT_EXTRA_DIRS "${CMAKE_INSTALL_INCLUDEDIR}/${PACKAGE_NAME}") + +configure_package_config_file( + ${PROJECT_SOURCE_DIR}/cmake/Templates/${PACKAGE_NAME}/config.cmake.in + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}/${PACKAGE_NAME}-config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} + INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} + PATH_VARS PROJECT_INSTALL_DIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR) + +write_basic_package_version_file( + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}/${PACKAGE_NAME}-config-version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMinorVersion) + +install( + FILES + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}/${PACKAGE_NAME}-config.cmake + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}/${PACKAGE_NAME}-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME} + COMPONENT rocpd) + +export(PACKAGE ${PACKAGE_NAME}) + +# ------------------------------------------------------------------------------# +# build tree +# +set(${PACKAGE_NAME}_BUILD_TREE + ON + CACHE BOOL "" FORCE) + +set(PROJECT_BUILD_TREE_TARGETS ${SDK_PACKAGE_NAME}::${PACKAGE_NAME}-shared-library + ${SDK_PACKAGE_NAME}::${SDK_PACKAGE_NAME}-stack-protector) + +configure_file( + ${PROJECT_SOURCE_DIR}/cmake/Templates/${PACKAGE_NAME}/build-config.cmake.in + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}/${PACKAGE_NAME}-build-config.cmake + @ONLY) + +file(RELATIVE_PATH rocp_bin2src_rel_path ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}) +string(REPLACE "//" "/" rocp_inc_rel_path "${rocp_bin2src_rel_path}/source/include") + +set(_BUILDTREE_EXPORT_DIR + "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PACKAGE_NAME}") + +execute_process( + COMMAND ${CMAKE_COMMAND} -E create_symlink ${rocp_inc_rel_path} + ${PROJECT_BINARY_DIR}/include WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) + +if(NOT EXISTS "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") +endif() + +if(NOT EXISTS "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/${PACKAGE_NAME}") + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/${PACKAGE_NAME}") +endif() + +if(NOT EXISTS "${_BUILDTREE_EXPORT_DIR}") + file(MAKE_DIRECTORY "${_BUILDTREE_EXPORT_DIR}") +endif() + +if(NOT EXISTS "${_BUILDTREE_EXPORT_DIR}/${PACKAGE_NAME}-targets.cmake") + file(TOUCH "${_BUILDTREE_EXPORT_DIR}/${PACKAGE_NAME}-targets.cmake") +endif() + +export( + EXPORT ${PACKAGE_NAME}-targets + NAMESPACE ${PACKAGE_NAME}:: + FILE "${_BUILDTREE_EXPORT_DIR}/${PACKAGE_NAME}-targets.cmake") + +set(${PACKAGE_NAME}_DIR + "${_BUILDTREE_EXPORT_DIR}" + CACHE PATH "${PACKAGE_NAME} build tree install" FORCE) + +install( + FILES ${PROJECT_SOURCE_DIR}/LICENSE + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/${PACKAGE_NAME} + COMPONENT rocpd) diff --git a/cmake/rocprofiler_config_packaging.cmake b/cmake/rocprofiler_config_packaging.cmake index fced05e79c..fc612b5406 100644 --- a/cmake/rocprofiler_config_packaging.cmake +++ b/cmake/rocprofiler_config_packaging.cmake @@ -58,13 +58,14 @@ list(REMOVE_ITEM ROCPROFILER_PACKAGING_COMPONENTS "Development" "Unspecified") list(LENGTH ROCPROFILER_PACKAGING_COMPONENTS NUM_ROCPROFILER_PACKAGING_COMPONENTS) # the packages we will generate -set(ROCPROFILER_COMPONENT_GROUPS "core" "docs" "tests" "roctx") +set(ROCPROFILER_COMPONENT_GROUPS "core" "docs" "tests" "roctx" "rocpd") set(COMPONENT_GROUP_core_COMPONENTS "core" "development" "samples" "tools" "benchmark" "Development" "Unspecified") set(COMPONENT_GROUP_docs_COMPONENTS "docs") set(COMPONENT_GROUP_tests_COMPONENTS "tests") set(COMPONENT_GROUP_roctx_COMPONENTS "roctx") +set(COMPONENT_GROUP_rocpd_COMPONENTS "rocpd") # variables for each component group. Note: eventually we will probably want to separate # the core to just be the runtime libraries, development to be the headers and cmake @@ -74,18 +75,25 @@ set(COMPONENT_NAME_core "rocprofiler-sdk") set(COMPONENT_NAME_docs "rocprofiler-sdk-docs") set(COMPONENT_NAME_tests "rocprofiler-sdk-tests") set(COMPONENT_NAME_roctx "rocprofiler-sdk-roctx") +set(COMPONENT_NAME_rocpd "rocprofiler-sdk-rocpd") -set(COMPONENT_DEP_core "rocprofiler-sdk-roctx (>= ${PROJECT_VERSION})") +set(COMPONENT_DEP_core "rocprofiler-sdk-roctx (>= ${PROJECT_VERSION})" + "rocprofiler-sdk-rocpd (>= ${PROJECT_VERSION})") set(COMPONENT_DEP_docs "") -set(COMPONENT_DEP_tests "rocprofiler-sdk (>= ${PROJECT_VERSION})") -set(COMPONENT_DEP_roctx "") +set(COMPONENT_DEP_tests + "rocprofiler-sdk (>= ${PROJECT_VERSION})" + "rocprofiler-sdk-roctx (>= ${PROJECT_VERSION})" + "rocprofiler-sdk-rocpd (>= ${PROJECT_VERSION})") +set(COMPONENT_DEP_roctx "rocprofiler-register") +set(COMPONENT_DEP_rocpd "") set(COMPONENT_DESC_core "rocprofiler-sdk libraries, headers, samples, and tools") set(COMPONENT_DESC_docs "rocprofiler-sdk documentation") set(COMPONENT_DESC_tests "rocprofiler-sdk tests") set(COMPONENT_DESC_roctx "ROCm Tools Extension library and headers") +set(COMPONENT_DESC_rocpd "ROCm Profiling Data library and headers") -set(EXPECTED_PACKAGING_COMPONENTS 6) +set(EXPECTED_PACKAGING_COMPONENTS 7) if(ROCPROFILER_BUILD_DOCS) math(EXPR EXPECTED_PACKAGING_COMPONENTS "${EXPECTED_PACKAGING_COMPONENTS} + 1") endif() diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index e864ded3f2..db4455b27d 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -272,12 +272,8 @@ if(ROCPROFILER_BUILD_SQLITE3) ) add_dependencies(rocprofiler-sdk-sqlite3 rocprofiler-sdk-sqlite-build) else() - # make it optional temporarily because ROCm CI does not have SQLite3 dev installed and - # cannot build from source (missing tclsh) - find_package(SQLite3) - if(SQLite3_FOUND) - target_link_libraries(rocprofiler-sdk-sqlite3 INTERFACE SQLite::SQLite3) - endif() + find_package(SQLite3 REQUIRED) + target_link_libraries(rocprofiler-sdk-sqlite3 INTERFACE SQLite::SQLite3) endif() # diff --git a/source/bin/CMakeLists.txt b/source/bin/CMakeLists.txt index 055969dbbd..d6bda044bc 100644 --- a/source/bin/CMakeLists.txt +++ b/source/bin/CMakeLists.txt @@ -5,8 +5,7 @@ rocprofiler_activate_clang_tidy() # Adding main rocprofv3 -configure_file(rocprofv3.py ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/rocprofv3 - COPYONLY) +configure_file(rocprofv3.py ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/rocprofv3 @ONLY) install( FILES ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/rocprofv3 diff --git a/source/bin/rocprofv3.py b/source/bin/rocprofv3.py index ebaabc44f2..d5d64aaf3a 100755 --- a/source/bin/rocprofv3.py +++ b/source/bin/rocprofv3.py @@ -22,11 +22,24 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -import argparse import os -import subprocess -import textwrap import sys +import argparse +import textwrap +import subprocess + +# version info for rocprofiler-sdk / rocprofv3 +CONST_VERSION_INFO = { + "version": "@FULL_VERSION_STRING@", + "git_revision": "@ROCPROFILER_SDK_GIT_REVISION@", + "library_arch": "@CMAKE_LIBRARY_ARCHITECTURE@", + "system_name": "@CMAKE_SYSTEM_NAME@", + "system_processor": "@CMAKE_SYSTEM_PROCESSOR@", + "system_version": "@CMAKE_SYSTEM_VERSION@", + "compiler_id": "@CMAKE_CXX_COMPILER_ID@", + "compiler_version": "@CMAKE_CXX_COMPILER_VERSION@", + "rocm_version": "@rocm_version_FULL_VERSION@", +} class dotdict(dict): @@ -171,6 +184,13 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins metavar="BOOL", ) + parser.add_argument( + "-v", + "--version", + action="store_true", + help="Print the version information and exit", + ) + io_options = parser.add_argument_group("I/O options") io_options.add_argument( @@ -196,11 +216,12 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins required=False, ) io_options.add_argument( + "-f", "--output-format", - help="For adding output format (supported formats: csv, json, pftrace, otf2)", + help="For adding output format (supported formats: csv, json, pftrace, otf2, rocpd)", nargs="+", default=None, - choices=("csv", "json", "pftrace", "otf2"), + choices=("csv", "json", "pftrace", "otf2", "rocpd"), type=str.lower, ) add_parser_bool_argument( @@ -1018,7 +1039,7 @@ def run(app_args, args, **kwargs): update_env("ROCPROF_OUTPUT_LIST_AVAIL_FILE", True) if not args.output_format: - args.output_format = ["csv"] + args.output_format = ["rocpd"] update_env( "ROCPROF_OUTPUT_FORMAT", ",".join(args.output_format), append=True, join_char="," @@ -1102,6 +1123,9 @@ def run(app_args, args, **kwargs): trace_count += 1 if val else 0 trace_opts += ["--{}".format(opt.replace("_", "-"))] + if args.pmc_groups: + trace_count += 1 + # if marker tracing was requested, LD_PRELOAD the rocprofiler-sdk-roctx library # to override the roctx symbols of an app linked to the old roctracer roctx if args.marker_trace and not args.suppress_marker_preload: @@ -1144,6 +1168,12 @@ def run(app_args, args, **kwargs): "\n ".join(trace_opts), ) + rocprofiler_ci_env = os.environ.get("ROCPROFILER_CI", "0") + if strtobool(rocprofiler_ci_env): + fatal_error( + f"rocprofv3 tracing options are required when ROCPROFILER_CI={rocprofiler_ci_env}" + ) + _summary_groups = "##@@##".join(args.summary_groups) if args.summary_groups else None _summary_output_fname = args.summary_output_file if args.summary and _summary_output_fname is None: @@ -1325,7 +1355,7 @@ def run(app_args, args, **kwargs): update_env("ROCPROF_EXTRA_COUNTERS_CONTENTS", e_file_contents, overwrite=True) if args.pmc and args.pmc_groups: - fatal_error("Cannot specify both --pmc and --pmc-groups") + fatal_error("Cannot specify both --pmc and (input file) pmc_groups") if args.pmc: update_env("ROCPROF_COUNTER_COLLECTION", True, overwrite=True) @@ -1522,6 +1552,12 @@ def run(app_args, args, **kwargs): def main(argv=None): cmd_args, app_args = parse_arguments(argv) + + if cmd_args.version: + for key, itr in CONST_VERSION_INFO.items(): + print(f" {key:>16}: {itr}") + return 0 + inp_args = ( parse_input(cmd_args.input) if getattr(cmd_args, "input") else [dotdict({})] ) @@ -1531,16 +1567,22 @@ def main(argv=None): pass_idx = None if has_set_attr(args, "pmc") and len(args.pmc) > 0: pass_idx = 1 - run(app_args, args, pass_id=pass_idx) + ec = run(app_args, args, pass_id=pass_idx) else: + ec = 0 for idx, itr in enumerate(inp_args): args = get_args(cmd_args, itr) - run( + _ec = run( app_args, args, pass_id=(idx + 1), use_execv=False, ) + if _ec is not None and _ec != 0: + ec = _ec + + # return error code + return ec if not None else 0 if __name__ == "__main__": diff --git a/source/include/CMakeLists.txt b/source/include/CMakeLists.txt index d0c7e1ba82..eb0f78e63c 100644 --- a/source/include/CMakeLists.txt +++ b/source/include/CMakeLists.txt @@ -5,3 +5,4 @@ set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "development") add_subdirectory(rocprofiler-sdk) add_subdirectory(rocprofiler-sdk-roctx) +add_subdirectory(rocprofiler-sdk-rocpd) diff --git a/source/include/rocprofiler-sdk-rocpd/CMakeLists.txt b/source/include/rocprofiler-sdk-rocpd/CMakeLists.txt new file mode 100644 index 0000000000..03a2c9722b --- /dev/null +++ b/source/include/rocprofiler-sdk-rocpd/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# +# Installation of public headers +# +# +configure_file(${CMAKE_CURRENT_LIST_DIR}/version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY) + +set(ROCPD_HEADER_FILES + # core headers + rocpd.h + # secondary headers + defines.h types.h ${CMAKE_CURRENT_BINARY_DIR}/version.h) + +install( + FILES ${ROCPD_HEADER_FILES} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rocprofiler-sdk-rocpd + COMPONENT rocpd) diff --git a/source/include/rocprofiler-sdk-rocpd/defines.h b/source/include/rocprofiler-sdk-rocpd/defines.h new file mode 100644 index 0000000000..485236275b --- /dev/null +++ b/source/include/rocprofiler-sdk-rocpd/defines.h @@ -0,0 +1,130 @@ +// MIT License +// +// Copyright (c) 2023-2025 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 + +/** + * @defgroup SYMBOL_VERSIONING_GROUP Symbol Versions + * + * @brief The names used for the shared library versioned symbols. + * + * Every function is annotated with one of the version macros defined in this + * section. Each macro specifies a corresponding symbol version string. After + * dynamically loading the shared library with @p dlopen, the address of each + * function can be obtained using @p dlsym with the name of the function and + * its corresponding symbol version string. An error will be reported by @p + * dlvsym if the installed library does not support the version for the + * function specified in this version of the interface. + * + * @{ + */ + +/** + * @brief The function was introduced in version 0.0 of the interface and has the + * symbol version string of ``"ROCPROFILER_SDK_ROCPD_0.0"``. + */ +#define ROCPROFILER_SDK_ROCPD_VERSION_0_0 + +/** @} */ + +#if !defined(ROCPD_ATTRIBUTE) +# if defined(_MSC_VER) +# define ROCPD_ATTRIBUTE(...) __declspec(__VA_ARGS__) +# else +# define ROCPD_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) +# endif +#endif + +#if !defined(ROCPD_PUBLIC_API) +# if defined(_MSC_VER) +# define ROCPD_PUBLIC_API ROCPD_ATTRIBUTE(dllexport) +# else +# define ROCPD_PUBLIC_API ROCPD_ATTRIBUTE(visibility("default")) +# endif +#endif + +#if !defined(ROCPD_HIDDEN_API) +# if defined(_MSC_VER) +# define ROCPD_HIDDEN_API +# else +# define ROCPD_HIDDEN_API ROCPD_ATTRIBUTE(visibility("hidden")) +# endif +#endif + +#if !defined(ROCPD_EXPORT_DECORATOR) +# define ROCPD_EXPORT_DECORATOR ROCPD_PUBLIC_API +#endif + +#if !defined(ROCPD_IMPORT_DECORATOR) +# if defined(_MSC_VER) +# define ROCPD_IMPORT_DECORATOR ROCPD_ATTRIBUTE(dllimport) +# else +# define ROCPD_IMPORT_DECORATOR +# endif +#endif + +#define ROCPD_EXPORT ROCPD_EXPORT_DECORATOR +#define ROCPD_IMPORT ROCPD_IMPORT_DECORATOR + +#if !defined(ROCPD_API) +# if defined(rocpd_EXPORTS) +# define ROCPD_API ROCPD_EXPORT +# else +# define ROCPD_API ROCPD_IMPORT +# endif +#endif + +#if defined(__has_attribute) +# if __has_attribute(nonnull) +# define ROCPD_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) +# else +# define ROCPD_NONNULL(...) +# endif +#else +# if defined(__GNUC__) +# define ROCPD_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) +# else +# define ROCPD_NONNULL(...) +# endif +#endif + +#ifdef __cplusplus +# define ROCPD_EXTERN_C_INIT extern "C" { +# define ROCPD_EXTERN_C_FINI } +#else +# define ROCPD_EXTERN_C_INIT +# define ROCPD_EXTERN_C_FINI +#endif + +#if !defined(ROCPD_EXPERIMENTAL_WARNINGS) +# define ROCPD_EXPERIMENTAL_WARNINGS 0 +#endif + +#define ROCPD_EXPERIMENTAL_MESSAGE \ + ROCPD_DEPRECATED_MESSAGE("Note: this feature has been marked as experimental. Define " \ + "ROCPD_EXPERIMENTAL_WARNINGS=0 to silence this message.") + +#if defined(ROCPD_EXPERIMENTAL_WARNINGS) && ROCPD_EXPERIMENTAL_WARNINGS > 0 +# define ROCPD_EXPERIMENTAL ROCPD_EXPERIMENTAL_MESSAGE +#else +# define ROCPD_EXPERIMENTAL +#endif diff --git a/source/include/rocprofiler-sdk-rocpd/rocpd.h b/source/include/rocprofiler-sdk-rocpd/rocpd.h new file mode 100644 index 0000000000..3ee0640188 --- /dev/null +++ b/source/include/rocprofiler-sdk-rocpd/rocpd.h @@ -0,0 +1,118 @@ +// MIT License +// +// Copyright (c) 2023-2025 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 + +/** + * @file rocpd.h + * @brief rocPD API interface for AMD profiling data analysis + * + * @mainpage rocPD API Specification + * + */ + +#include "rocprofiler-sdk-rocpd/defines.h" +#include "rocprofiler-sdk-rocpd/types.h" + +/** + * @defgroup VERSIONING_GROUP Library Versioning + * @brief Version information about the interface and the associated installed library. + * + * The semantic version of the interface following semver.org rules. A context + * that uses this interface is only compatible with the installed library if + * the major version numbers match and the interface minor version number is + * less than or equal to the installed library minor version number. + * + * @{ + */ + +#include "rocprofiler-sdk-rocpd/version.h" + +ROCPD_EXTERN_C_INIT + +/** + * @fn rocpd_status_t rocpd_get_version(uint32_t* major, uint32_t* minor, uint32_t* + * patch) + * @brief Query the version of the installed library. + * + * Returns the version of the rocprofiler-sdk library loaded at runtime. This can be used to check + * if the runtime version is equal to or compatible with the version of rocprofiler-sdk used during + * compilation time. This function can be invoked before tool initialization. + * + * @param [out] major The major version number is stored if non-NULL. + * @param [out] minor The minor version number is stored if non-NULL. + * @param [out] patch The patch version number is stored if non-NULL. + * @return ::rocpd_status_t + * @retval ::ROCPD_STATUS_SUCCESS Always returned + */ +rocpd_status_t +rocpd_get_version(uint32_t* major, uint32_t* minor, uint32_t* patch) ROCPD_API; + +/** + * @brief Simplified alternative to ::rocpd_get_version + * + * Returns the version of the rocprofiler-sdk library loaded at runtime. This can be used to check + * if the runtime version is equal to or compatible with the version of rocprofiler-sdk used during + * compilation time. This function can be invoked before tool initialization. + * + * @param [out] info Pointer to version triplet struct which will be populated by the function call. + * @return ::rocpd_status_t + * @retval ::ROCPD_STATUS_SUCCESS Always returned + */ +rocpd_status_t +rocpd_get_version_triplet(rocpd_version_triplet_t* info) ROCPD_API ROCPD_NONNULL(1); + +ROCPD_EXTERN_C_FINI + +/** @} */ + +#include "rocprofiler-sdk-rocpd/sql.h" + +ROCPD_EXTERN_C_INIT + +/** + * @defgroup MISCELLANEOUS_GROUP Miscellaneous Utility Functions + * @brief utility functions for library + * @{ + */ + +/** + * @fn const char* rocpd_get_status_name(rocpd_status_t status) + * @brief Return the string encoding of ::rocpd_status_t value + * @param [in] status error code value + * @return Will return a nullptr if invalid/unsupported ::rocpd_status_t value is provided. + */ +const char* +rocpd_get_status_name(rocpd_status_t status) ROCPD_API; + +/** + * @fn const char* rocpd_get_status_string(rocpd_status_t status) + * @brief Return the message associated with ::rocpd_status_t value + * @param [in] status error code value + * @return Will return a nullptr if invalid/unsupported ::rocpd_status_t value is provided. + */ +const char* +rocpd_get_status_string(rocpd_status_t status) ROCPD_API; + +/** @} */ + +ROCPD_EXTERN_C_FINI diff --git a/source/include/rocprofiler-sdk-rocpd/sql.h b/source/include/rocprofiler-sdk-rocpd/sql.h new file mode 100644 index 0000000000..31b301cbd1 --- /dev/null +++ b/source/include/rocprofiler-sdk-rocpd/sql.h @@ -0,0 +1,151 @@ +// MIT License +// +// Copyright (c) 2023-2025 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 +#include + +#include + +ROCPD_EXTERN_C_INIT + +/** + * @defgroup SQL rocPD SQL Utilities + * @brief Functions for reading rocpd SQL schema + * @{ + */ + +/** + * @brief (experimental) Supported SQL engines. Initial support is for SQLite3, other engines such + * as MySQL may be added + */ +typedef enum ROCPD_EXPERIMENTAL rocpd_sql_engine_t +{ + ROCPD_SQL_ENGINE_NONE = 0, + ROCPD_SQL_ENGINE_SQLITE3, ///< Ensure compatibility with SQLite3 + ROCPD_SQL_ENGINE_LAST, +} rocpd_sql_engine_t; + +/** + * @brief (experimental) Supported SQL schema kinds + */ +typedef enum ROCPD_EXPERIMENTAL rocpd_sql_schema_kind_t +{ + ROCPD_SQL_SCHEMA_NONE = 0, + ROCPD_SQL_SCHEMA_ROCPD_TABLES, + ROCPD_SQL_SCHEMA_ROCPD_INDEXES, + ROCPD_SQL_SCHEMA_ROCPD_VIEWS, + ROCPD_SQL_SCHEMA_ROCPD_DATA_VIEWS, + ROCPD_SQL_SCHEMA_ROCPD_SUMMARY_VIEWS, + ROCPD_SQL_SCHEMA_ROCPD_MARKER_VIEWS, + ROCPD_SQL_SCHEMA_LAST, +} rocpd_sql_schema_kind_t; + +/** + * @brief (experimental) Supported SQL options + */ +typedef enum ROCPD_EXPERIMENTAL rocpd_sql_options_t +{ + ROCPD_SQL_OPTIONS_NONE = 0, + ROCPD_SQL_OPTIONS_PERSIST_STRINGS = 0x01, ///< do not delete strings + ROCPD_SQL_OPTIONS_SQLITE3_PRAGMA_FOREIGN_KEYS = 0x02, ///< enable SQLite3 foreign keys + ROCPD_SQL_OPTIONS_LAST = 0xFFFFFFFF, +} rocpd_sql_options_t; + +/** + * @brief (experimental) Schema jinja variable substitution values. In general, the struct member + * variable replaces jinja variables of the same name, e.g. the struct member variable `uuid` + * replaces `{{uuid}}` in the schema definition. + * + * When the schema variable `{{uuid}}` is a non-null and non-empty string, it + * will be prefixed with a leading underscore (`_`) and all hyphens will be replaced with + * underscores. This is because this variable is used in SQL table names. The leading + * underscore improves the readability of the table name and the replacement of hyphens with + * underscores is reduces problems. + */ +typedef struct ROCPD_EXPERIMENTAL rocpd_sql_schema_jinja_variables_t +{ + uint64_t size; ///< Size of this struct (minus reserved padding) + const char* uuid; ///< Substitution for `{{uuid}}` (non-empty adds leading underscore) + const char* guid; ///< Substitution for `{{guid}}` +} rocpd_sql_schema_jinja_variables_t; + +/** + * @brief (experimental) Callback providing the schema content after variable substitution. + * + * @param [in] engine Schema conforms to this SQL database engine + * @param [in] kind Schema category + * @param [in] options Schema options included in content + * @param [in] variables Jinja variables which were substituted + * @param [in] schema_path Filesystem path to base schema file + * @param [in] schema_content SQL schema content is pass to database + * @param [in] user_data User provided data + */ +ROCPD_EXPERIMENTAL typedef void (*rocpd_sql_load_schema_cb_t)( + rocpd_sql_engine_t engine, + rocpd_sql_schema_kind_t kind, + rocpd_sql_options_t options, + const rocpd_sql_schema_jinja_variables_t* variables, + const char* schema_path, + const char* schema_content, + void* user_data); + +/** + * @brief (experimental) Invoke the callback which provides the schema kind definition for the given + * SQL engine + the addition of the requested options + jinja variable substitution. + * + * @param [in] engine SQL schema contents should be compatible with this SQL database engine + * @param [in] kind SQL schema kind (tables, indexes, views, etc.) + * @param [in] options Options for the callback and schema + * @param [in] variables Defines variables for jinja substitution. If nullptr, no jinja variables + * will be substituted. For each member variable that is a nullptr, jinja for that member variable + * will not be substituted. To replace jinja variables with empty strings, assign all member + * variables to empty string. + * @param [in] callback Callback function which provides the schema contents + * @param [in] schema_path_hints Suggests for where to find the schema templates + * @param [in] num_schema_path_hints Number of schema path hints + * @param [in] user_data Pointer to pass back into callback + * @return ::rocpd_status_t + * @retval ROCPD_STATUS_SUCCESS if all parameter specifications were applied and callback + * successfully invoked + * @retval ROCPD_STATUS_ERROR_INVALID_ARGUMENT Invalid SQL engine + * @retval ROCPD_STATUS_ERROR_NOT_AVAILABLE Schema file could not be found + * @retval ROCPD_STATUS_ERROR_PERMISSION_DENIED Schema file could not be found + * @retval ROCPD_STATUS_ERROR_KIND_NOT_FOUND Invalid SQL schema kind + * @retval ROCPD_STATUS_ERROR There was some issue with parameters + * @retval ROCPD_STATUS_ERROR_INVALID_ARGUMENT ::rocpd_sql_schema_jinja_variables_t size parameter + * not set + */ +ROCPD_EXPERIMENTAL rocpd_status_t +rocpd_sql_load_schema(rocpd_sql_engine_t engine, + rocpd_sql_schema_kind_t kind, + rocpd_sql_options_t options, + const rocpd_sql_schema_jinja_variables_t* variables, + rocpd_sql_load_schema_cb_t callback, + const char** schema_path_hints, + uint64_t num_schema_path_hints, + void* user_data) ROCPD_API ROCPD_NONNULL(5); + +/** @} */ + +ROCPD_EXTERN_C_FINI diff --git a/source/include/rocprofiler-sdk-rocpd/types.h b/source/include/rocprofiler-sdk-rocpd/types.h new file mode 100644 index 0000000000..6ebbe92d27 --- /dev/null +++ b/source/include/rocprofiler-sdk-rocpd/types.h @@ -0,0 +1,81 @@ +// MIT License +// +// Copyright (c) 2023-2025 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-rocpd/defines.h" + +#include + +/** @defgroup DATA_TYPE rocPD Data types + * + * Data types defined or aliased by rocPD + * + * @{ + */ + +//--------------------------------------------------------------------------------------// +// +// ENUMERATIONS +// +//--------------------------------------------------------------------------------------// + +/** + * @defgroup BASIC_DATA_TYPES Basic data types + * @brief Basic data types and typedefs + * + * @{ + */ + +/** + * @brief Status codes. + */ +typedef enum rocpd_status_t // NOLINT(performance-enum-size) +{ + ROCPD_STATUS_SUCCESS = 0, ///< No error occurred + ROCPD_STATUS_ERROR, ///< Generalized error + ROCPD_STATUS_ERROR_INVALID_ARGUMENT, ///< Argument is invalid + ROCPD_STATUS_ERROR_SQL_ERROR, ///< General SQL error + ROCPD_STATUS_ERROR_SQL_INVALID_ENGINE, ///< SQL engine is invalid + ROCPD_STATUS_ERROR_SQL_INVALID_SCHEMA_KIND, ///< SQL schema kind not found + ROCPD_STATUS_ERROR_SQL_SCHEMA_NOT_FOUND, ///< SQL schema does not exist + ROCPD_STATUS_ERROR_SQL_SCHEMA_PERMISSION_DENIED, ///< SQL schema not accessible + ROCPD_STATUS_LAST, +} rocpd_status_t; + +//--------------------------------------------------------------------------------------// +// +// STRUCTS +// +//--------------------------------------------------------------------------------------// + +/** + * @brief Versioning info. + */ +typedef struct rocpd_version_triplet_t +{ + uint32_t major; + uint32_t minor; + uint32_t patch; +} rocpd_version_triplet_t; + +/** @} */ diff --git a/source/include/rocprofiler-sdk-rocpd/version.h.in b/source/include/rocprofiler-sdk-rocpd/version.h.in new file mode 100644 index 0000000000..fcc4f0d7e5 --- /dev/null +++ b/source/include/rocprofiler-sdk-rocpd/version.h.in @@ -0,0 +1,115 @@ +// MIT License +// +// Copyright (c) 2023-2025 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 + +/** + * @def ROCPD_IS_ROCPROFILER_SDK + * @brief Preprocessor define indicating the rocpd header is a rocprofiler-sdk project + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_VERSION_MAJOR + * @brief The major version of the interface as a macro so it can be used + * by the preprocessor. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_VERSION_MINOR + * @brief The minor version of the interface as a macro so it can be used + * by the preprocessor. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_VERSION_PATCH + * @brief The patch version of the interface as a macro so it can be used + * by the preprocessor. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_VERSION + * @brief Numerically increasing version number encoding major, minor, and patch via + computing `((10000 * ) + (100 * ) + )`. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_SOVERSION + * @brief Shared object versioning value whose value is at least `(10000 * )`. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_VERSION_STRING + * @brief Version string in form: `..`. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_GIT_DESCRIBE + * @brief String encoding of `git describe --tags` when rocprofiler was built. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_GIT_REVISION + * @brief String encoding of `git rev-parse HEAD` when rocprofiler was built. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_LIBRARY_ARCH + * @brief Architecture triplet of rocprofiler build. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_SYSTEM_NAME + * @brief Target operating system for rocprofiler build, e.g. Linux. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_SYSTEM_PROCESSOR + * @brief Target architecture for rocprofiler build. + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_SYSTEM_VERSION + * @brief Version of the operating system which built rocprofiler + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_COMPILER_ID + * @brief C++ compiler identifier which built rocprofiler, e.g., GNU + * @addtogroup VERSIONING_GROUP + * + * @def ROCPD_COMPILER_VERSION + * @brief C++ compiler version which built rocprofiler + * @addtogroup VERSIONING_GROUP + */ + +#define ROCPD_IS_ROCPROFILER_SDK 1 + +// clang-format off +#define ROCPD_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define ROCPD_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define ROCPD_VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define ROCPD_SOVERSION (10000 * @PROJECT_VERSION_MAJOR@) +#define ROCPD_VERSION_STRING "@FULL_VERSION_STRING@" +#define ROCPD_GIT_DESCRIBE "@ROCPROFILER_SDK_GIT_DESCRIBE@" +#define ROCPD_GIT_REVISION "@ROCPROFILER_SDK_GIT_REVISION@" + +// system info during compilation +#define ROCPD_LIBRARY_ARCH "@CMAKE_LIBRARY_ARCHITECTURE@" +#define ROCPD_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@" +#define ROCPD_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@" +#define ROCPD_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@" + +// compiler information +#define ROCPD_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@" +#define ROCPD_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@" + +// clang-format on + +#define ROCPD_VERSION \ + ((10000 * ROCPD_VERSION_MAJOR) + (100 * ROCPD_VERSION_MINOR) + ROCPD_VERSION_PATCH) diff --git a/source/include/rocprofiler-sdk/cxx/serialization/save.hpp b/source/include/rocprofiler-sdk/cxx/serialization/save.hpp index 97f2dae792..23cc0ac751 100644 --- a/source/include/rocprofiler-sdk/cxx/serialization/save.hpp +++ b/source/include/rocprofiler-sdk/cxx/serialization/save.hpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include diff --git a/source/lib/CMakeLists.txt b/source/lib/CMakeLists.txt index 18445e7622..6989fe5337 100644 --- a/source/lib/CMakeLists.txt +++ b/source/lib/CMakeLists.txt @@ -8,9 +8,14 @@ add_subdirectory(common) add_subdirectory(output) add_subdirectory(rocprofiler-sdk) +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "roctx") +add_subdirectory(rocprofiler-sdk-roctx) + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "rocpd") +add_subdirectory(rocprofiler-sdk-rocpd) + set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "tools") add_subdirectory(att-tool) -add_subdirectory(rocprofiler-sdk-roctx) add_subdirectory(rocprofiler-sdk-tool) add_subdirectory(python) diff --git a/source/lib/common/CMakeLists.txt b/source/lib/common/CMakeLists.txt index 4fd1182885..ab4aae3da3 100644 --- a/source/lib/common/CMakeLists.txt +++ b/source/lib/common/CMakeLists.txt @@ -9,11 +9,13 @@ set(common_sources environment.cpp logging.cpp md5sum.cpp + sha256.cpp simple_timer.cpp static_object.cpp static_tl_object.cpp string_entry.cpp - utility.cpp) + utility.cpp + uuid_v7.cpp) set(common_headers abi.hpp defines.hpp @@ -26,6 +28,7 @@ set(common_headers md5sum.hpp mpl.hpp scope_destructor.hpp + sha256.hpp simple_timer.hpp static_object.hpp static_tl_object.hpp @@ -33,7 +36,8 @@ set(common_headers stringize_arg.hpp synchronized.hpp units.hpp - utility.hpp) + utility.hpp + uuid_v7.hpp) add_library(rocprofiler-sdk-common-library STATIC) add_library(rocprofiler-sdk::rocprofiler-sdk-common-library ALIAS diff --git a/source/lib/common/environment.cpp b/source/lib/common/environment.cpp index 8f7cd4d045..f100dabb09 100644 --- a/source/lib/common/environment.cpp +++ b/source/lib/common/environment.cpp @@ -151,5 +151,56 @@ SPECIALIZE_SET_ENV(std::string_view) SPECIALIZE_SET_ENV(float) SPECIALIZE_SET_ENV(double) } // namespace impl + +env_store::env_store(std::initializer_list&& _container) +{ + for(const auto& itr : _container) + { + m_original.emplace_back(env_config{itr.env_name, get_env(itr.env_name, ""), 1}); + m_modified.emplace_back(env_config{itr.env_name, itr.env_value, 1}); + } +} + +env_store::~env_store() { pop(); } + +bool +env_store::push() +{ + // not that push ignored bc already pushed + if(m_pushed) return false; + + for(const auto& itr : m_modified) + itr(); + + m_pushed = true; + return true; +} + +bool +env_store::pop(bool unset_if_empty) +{ + if(!m_pushed) return false; + + for(const auto& itr : m_original) + { + auto _current = get_env(itr.env_name, ""); + if(!unset_if_empty && itr.env_value.empty()) + continue; + else if(_current == itr.env_value) + continue; + else if(_current != itr.env_value) + { + ROCP_INFO << fmt::format("[rocprofiler][env][pop] {}=\"{}\" => {}=\"{}\"", + itr.env_name, + _current, + itr.env_name, + itr.env_value); + } + itr(); + } + + m_pushed = false; + return true; +} } // namespace common } // namespace rocprofiler diff --git a/source/lib/common/environment.hpp b/source/lib/common/environment.hpp index 7fe6c3878f..a3feb7ce8c 100644 --- a/source/lib/common/environment.hpp +++ b/source/lib/common/environment.hpp @@ -88,11 +88,49 @@ struct env_config auto operator()(bool _verbose = false) const { - if(env_name.empty()) return -1; - ROCP_INFO_IF(_verbose) << "[rocprofiler][set_env] setenv(\"" << env_name << "\", \"" - << env_value << "\", " << overwrite << ")\n"; - return setenv(env_name.c_str(), env_value.c_str(), overwrite); + if(env_name.empty()) + return -1; + else if(_verbose) + { + ROCP_INFO << "[rocprofiler][set_env] setenv(\"" << env_name << "\", \"" << env_value + << "\", " << overwrite << ")\n"; + } + return (env_value.empty() && overwrite > 0) + ? unsetenv(env_name.c_str()) + : setenv(env_name.c_str(), env_value.c_str(), overwrite); } }; + +struct env_store +{ + template