├── .clang-format ├── .clang-tidy ├── .gitignore ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── backend ├── .pre-commit-config.yaml ├── CMakeLists.txt ├── LICENSE.md ├── README.md └── device │ ├── CMakeLists.txt │ ├── README.md │ ├── include │ └── device │ │ ├── api.hpp │ │ ├── constants.hpp │ │ ├── handle.hpp │ │ ├── hwcnt │ │ ├── block_extents.hpp │ │ ├── block_iterator.hpp │ │ ├── block_metadata.hpp │ │ ├── blocks_view.hpp │ │ ├── detail │ │ │ └── handle.hpp │ │ ├── features.hpp │ │ ├── prfcnt_set.hpp │ │ ├── reader.hpp │ │ ├── sample.hpp │ │ └── sampler │ │ │ ├── configuration.hpp │ │ │ ├── detail │ │ │ └── backend.hpp │ │ │ ├── manual.hpp │ │ │ └── periodic.hpp │ │ ├── instance.hpp │ │ └── product_id.hpp │ └── src │ └── device │ ├── detail │ ├── cast_to_impl.hpp │ ├── enum_operators.hpp │ └── is_empty_class.hpp │ ├── handle.cpp │ ├── handle_impl.hpp │ ├── hwcnt │ ├── backend_type.cpp │ ├── backend_type.hpp │ ├── reader.cpp │ └── sampler │ │ ├── base │ │ ├── backend.hpp │ │ └── backend_args.hpp │ │ ├── detail │ │ └── backend.cpp │ │ ├── discard_impl.hpp │ │ ├── filefd_guard.hpp │ │ ├── filter_block_extents.hpp │ │ ├── kinstr_prfcnt │ │ ├── backend.hpp │ │ ├── backend_args.hpp │ │ ├── backend_wa.hpp │ │ ├── block_index_remap.cpp │ │ ├── block_index_remap.hpp │ │ ├── construct_block_extents.hpp │ │ ├── convert.hpp │ │ ├── enum_info_parser.cpp │ │ ├── enum_info_parser.hpp │ │ ├── metadata_parser.cpp │ │ ├── metadata_parser.hpp │ │ ├── parse_all.hpp │ │ └── setup.hpp │ │ ├── mapped_memory.hpp │ │ ├── poll.hpp │ │ ├── queue.hpp │ │ ├── timestamp.hpp │ │ └── vinstr │ │ ├── backend.hpp │ │ ├── backend_args.hpp │ │ ├── construct_block_extents.hpp │ │ ├── convert.hpp │ │ ├── sample_layout.hpp │ │ ├── session.hpp │ │ └── setup.hpp │ ├── instance.cpp │ ├── instance_impl.hpp │ ├── ioctl │ ├── kbase │ │ ├── commands.hpp │ │ ├── compare.hpp │ │ ├── compare_manual.hpp │ │ ├── print.hpp │ │ ├── print_manual.hpp │ │ └── types.hpp │ ├── kbase_pre_r21 │ │ ├── commands.hpp │ │ ├── compare.hpp │ │ ├── compare_manual.hpp │ │ ├── print.hpp │ │ ├── print_manual.hpp │ │ └── types.hpp │ ├── kinstr_prfcnt │ │ ├── commands.hpp │ │ ├── compare.hpp │ │ ├── compare_manual.hpp │ │ ├── print.hpp │ │ ├── print_manual.hpp │ │ └── types.hpp │ ├── offset_pointer.hpp │ ├── pointer64.hpp │ ├── strided_array_iterator.hpp │ ├── strided_array_view.hpp │ └── vinstr │ │ ├── commands.hpp │ │ ├── compare.hpp │ │ ├── compare_manual.hpp │ │ ├── print.hpp │ │ ├── print_manual.hpp │ │ └── types.hpp │ ├── kbase_version.hpp │ ├── num_exec_engines.cpp │ ├── num_exec_engines.hpp │ ├── product_id.cpp │ ├── shader_core_bitset.hpp │ └── syscall │ ├── funcs │ ├── libmali.hpp │ └── unix.hpp │ └── iface.hpp ├── cmake ├── Catch.cmake ├── CatchAddTests.cmake └── toolchains │ ├── aarch64-android-clang.toolchain.cmake │ ├── arm-android-clang.toolchain.cmake │ └── lib │ └── android.toolchain.cmake ├── examples ├── CMakeLists.txt └── api_example.cpp ├── hwcpipe ├── CMakeLists.txt ├── include │ └── hwcpipe │ │ ├── counter_database.hpp │ │ ├── detail │ │ ├── assert.hpp │ │ ├── counter_database.hpp │ │ └── internal_types.hpp │ │ ├── error.hpp │ │ ├── gpu.hpp │ │ ├── hwcpipe.hpp │ │ ├── hwcpipe_counter.h │ │ ├── sampler.hpp │ │ └── types.hpp └── src │ ├── error.cpp │ └── hwcpipe │ ├── all_gpu_counters.cpp │ ├── all_gpu_counters.hpp │ ├── counter_metadata.cpp │ ├── counter_metadata.hpp │ ├── derived_functions.cpp │ ├── derived_functions.hpp │ └── detail │ └── counter_database.cpp ├── test ├── CMakeLists.txt ├── counter-sampler.cpp ├── dummy-test.cpp ├── hwcpipe │ ├── counter_enumeration.cpp │ ├── gpu_instance.cpp │ ├── hwcpipe_double.cpp │ └── mock │ │ ├── backend_manual_sampler.hpp │ │ ├── backend_sample.hpp │ │ ├── handle.hpp │ │ ├── instance.hpp │ │ └── mock_helper.h └── main.cpp ├── third_party ├── .clang-format ├── .clang-tidy └── catch2 │ ├── CMakeLists.txt │ └── vendor │ └── catch2 │ └── catch.hpp └── third_party_licenses.txt /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: LLVM 3 | IndentWidth: 4 4 | ColumnLimit: 120 5 | AlwaysBreakTemplateDeclarations: Yes 6 | BreakConstructorInitializers: BeforeComma 7 | IncludeBlocks: Regroup 8 | IncludeCategories: 9 | # Local includes 10 | - Regex: '".*"' 11 | Priority: 0 12 | # Catch2 includes 13 | - Regex: '^$' 17 | Priority: 2 18 | # stdc++ includes, e.g. 19 | - Regex: '^<[a-z_]+>$' 20 | Priority: 3 21 | # System includes 22 | - Regex: '^$' 23 | Priority: 4 24 | # All other includes. 25 | - Regex: '.*' 26 | Priority: 99 27 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: >- 3 | clang-diagnostic-*, 4 | clang-analyzer-*, 5 | modernize-use-nullptr, 6 | readability-identifier-naming, 7 | bugprone-*, 8 | -bugprone-easily-swappable-parameters, 9 | cppcoreguidelines-avoid-goto, 10 | cppcoreguidelines-c-copy-assignment-signature, 11 | cppcoreguidelines-explicit-virtual-functions, 12 | cppcoreguidelines-init-variables, 13 | cppcoreguidelines-interfaces-global-init, 14 | cppcoreguidelines-narrowing-conversions, 15 | cppcoreguidelines-no-malloc, 16 | cppcoreguidelines-owning-memory, 17 | cppcoreguidelines-pro-type-cstyle-cast, 18 | cppcoreguidelines-pro-type-member-init, 19 | cppcoreguidelines-pro-type-reinterpret-cast 20 | WarningsAsErrors: '*' 21 | HeaderFilterRegex: '^.*/github/(hwcpipe|test|examples)/.*\.hpp$' 22 | FormatStyle: file 23 | CheckOptions: 24 | - key: llvm-else-after-return.WarnOnConditionVariables 25 | value: '0' 26 | - key: modernize-loop-convert.MinConfidence 27 | value: reasonable 28 | - key: modernize-replace-auto-ptr.IncludeStyle 29 | value: llvm 30 | - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons 31 | value: '0' 32 | - key: google-readability-namespace-comments.ShortNamespaceLines 33 | value: '10' 34 | - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField 35 | value: '0' 36 | - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic 37 | value: '1' 38 | - key: cert-dcl16-c.NewSuffixes 39 | value: 'L;LL;LU;LLU' 40 | - key: google-readability-braces-around-statements.ShortStatementLines 41 | value: '1' 42 | - key: modernize-pass-by-value.IncludeStyle 43 | value: llvm 44 | - key: google-readability-namespace-comments.SpacesBeforeComments 45 | value: '2' 46 | - key: modernize-loop-convert.MaxCopySize 47 | value: '16' 48 | - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors 49 | value: '1' 50 | - key: modernize-use-nullptr.NullMacros 51 | value: 'NULL' 52 | - key: llvm-qualified-auto.AddConstToQualified 53 | value: '0' 54 | - key: modernize-loop-convert.NamingStyle 55 | value: CamelCase 56 | - key: llvm-else-after-return.WarnOnUnfixable 57 | value: '0' 58 | - key: google-readability-function-size.StatementThreshold 59 | value: '800' 60 | - key: readability-identifier-naming.MacroDefinitionCase 61 | value: 'UPPER_CASE' 62 | - key: readability-identifier-naming.NamespaceCase 63 | value: 'lower_case' 64 | - key: readability-identifier-naming.FunctionCase 65 | value: 'lower_case' 66 | - key: readability-identifier-naming.ParameterCase 67 | value: 'lower_case' 68 | - key: readability-identifier-naming.VariableCase 69 | value: 'lower_case' 70 | - key: readability-identifier-naming.EnumCase 71 | value: 'lower_case' 72 | - key: readability-identifier-naming.EnumConstantCase 73 | value: 'lower_case' 74 | - key: readability-identifier-naming.ClassCase 75 | value: 'lower_case' 76 | - key: readability-identifier-naming.StructCase 77 | value: 'lower_case' 78 | - key: readability-identifier-naming.UnionCase 79 | value: 'lower_case' 80 | - key: readability-identifier-naming.MemberCase 81 | value: 'lower_case' 82 | - key: readability-identifier-naming.PrivateMemberSuffix 83 | value: '_' 84 | - key: readability-identifier-naming.ProtectedMemberSuffix 85 | value: '_' 86 | - key: readability-identifier-naming.MethodCase 87 | value: 'lower_case' 88 | - key: readability-identifier-naming.TypeAliasCase 89 | value: 'lower_case' 90 | - key: readability-identifier-naming.TemplateParameterCase 91 | value: 'lower_case' 92 | - key: readability-identifier-naming.TypeTemplateParameterSuffix 93 | value: '_t' 94 | - key: readability-identifier-naming.ValueTemplateParameterSuffix 95 | value: '_v' 96 | ... 97 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | .clangd/ 3 | .cache/ 4 | .vscode/ 5 | __pycache__ 6 | compile_commands.json -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021-2023 Arm Limited. 3 | # 4 | # SPDX-License-Identifier: MIT 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.13.5) 8 | 9 | project(hwcpipe VERSION 2.3) 10 | 11 | set(CMAKE_CXX_STANDARD 14) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS OFF) 14 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 15 | 16 | option( 17 | HWCPIPE_WALL 18 | "Enable all warnings." 19 | ON 20 | ) 21 | option( 22 | HWCPIPE_WERROR 23 | "Treat compile and link warning as error." 24 | ON 25 | ) 26 | option( 27 | HWCPIPE_PIC 28 | "Generate position independent code." 29 | ON 30 | ) 31 | # Hwcpipe is designed for integration into game engines so RTTI and exceptions should not be used in this library. 32 | # They are, however, useful for unit tests so the compiler flags may be conditionally enabled for that purpose. 33 | option( 34 | HWCPIPE_ENABLE_RTTI 35 | "If set, C++ RTTI is enabled. Note that exceptions are required for Catch2." 36 | OFF 37 | ) 38 | option( 39 | HWCPIPE_ENABLE_EXCEPTIONS 40 | "If set, C++ exceptions are enabled." 41 | OFF 42 | ) 43 | option( 44 | HWCPIPE_FRONTEND_ENABLE_TESTS 45 | "Build the hwcpipe unit & integration tests. Note that RTTI and exceptions are required to build the tests." 46 | OFF 47 | ) 48 | option( 49 | HWCPIPE_BUILD_EXAMPLES 50 | "Build the example programs." 51 | OFF 52 | ) 53 | 54 | if(CMAKE_BUILD_TYPE 55 | AND (NOT 56 | CMAKE_BUILD_TYPE 57 | STREQUAL 58 | "Debug" 59 | ) 60 | ) 61 | set(IS_RELEASE_BUILD YES) 62 | endif() 63 | 64 | option( 65 | HWCPIPE_ENABLE_LTO 66 | "Enable link time optimization. Enabled by default for release builds." 67 | ${IS_RELEASE_BUILD} 68 | ) 69 | 70 | if (HWCPIPE_ENABLE_EXCEPTIONS) 71 | add_compile_options(-fexceptions) 72 | else() 73 | add_compile_options(-fno-exceptions) 74 | endif() 75 | 76 | if (HWCPIPE_ENABLE_RTTI) 77 | add_compile_options(-frtti) 78 | else() 79 | add_compile_options(-fno-rtti) 80 | endif() 81 | 82 | if(HWCPIPE_WERROR) 83 | add_compile_options( 84 | -Werror 85 | -pedantic-errors 86 | -Wno-abi # Silence GCC 7.1 ABI compatibility warning 87 | ) 88 | add_link_options(-Werror) 89 | endif() 90 | 91 | add_subdirectory(backend/device) 92 | 93 | if(HWCPIPE_PIC) 94 | set_target_properties(device PROPERTIES POSITION_INDEPENDENT_CODE ON) 95 | endif() 96 | 97 | add_subdirectory(hwcpipe) 98 | 99 | if(HWCPIPE_BUILD_EXAMPLES) 100 | add_subdirectory(examples) 101 | endif() 102 | 103 | if(HWCPIPE_FRONTEND_ENABLE_TESTS) 104 | if (NOT HWCPIPE_ENABLE_EXCEPTIONS) 105 | message(FATAL_ERROR "HWCPIPE_FRONTEND_ENABLE_TESTS=ON requires HWCPIPE_ENABLE_EXCEPTIONS=ON.") 106 | endif() 107 | if (NOT HWCPIPE_ENABLE_RTTI) 108 | message(FATAL_ERROR "HWCPIPE_FRONTEND_ENABLE_TESTS=ON requires HWCPIPE_ENABLE_RTTI=ON.") 109 | endif() 110 | 111 | enable_testing() 112 | include(CTest) 113 | include(cmake/Catch.cmake) 114 | 115 | add_compile_definitions(HWCPIPE_TEST=1) 116 | 117 | add_subdirectory(test) 118 | add_subdirectory(third_party/catch2) 119 | endif() 120 | 121 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Arm Limited 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or 11 | substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | libGPUCounters (formerly called HWCPipe) is a utility that allows applications to sample performance 4 | counters from Arm® Immortalis™ and Arm Mali™ GPUs. This information allows developers to profile and 5 | optimize their application workload using their existing in-house performance tooling, and gives the 6 | ability to display performance data live in the application user interface. 7 | 8 | The 2.x release series is a major rewrite of the library, capable of exposing all of the public 9 | performance counters accessible in the Arm Streamline profiler. This version of the library 10 | is not API compatible with the 1.x series, and no longer supports Arm CPU performance counters. 11 | 12 | ## Supported devices 13 | 14 | This library aims to support all Arm GPU products from the Mali-T700 series onwards, ensuring 15 | developers have coverage of the vast majority of smartphones with Arm GPUs that are in use today. 16 | If you find a device with an Arm GPU which does not work, or gives inaccurate results, please open 17 | an Issue on the GitHub issue tracker. 18 | 19 | This library only supports devices using the Arm commercial driver. 20 | 21 | ## License 22 | 23 | This project is licensed under the MIT license. By downloading any component from this repository 24 | you acknowledge that you accept terms specified in the [LICENSE.md](LICENSE.md) file. 25 | 26 | # Building 27 | 28 | The library is designed to be embedded into existing CMake build process. Clone the GitHub 29 | repository and add it as a subdirectory to your CMakeLists.txt. A single library target, called 30 | `hwcpipe`, is made available for you to link to your project. 31 | 32 | For example, your `CMakeLists.txt` could contain: 33 | 34 | ``` 35 | add_subdirectory(external/hwcpipe) 36 | target_link_libraries(my_project hwcpipe) 37 | ``` 38 | 39 | ## Building the example 40 | 41 | A small example demonstrating the API usage is provided in the `examples` folder. To build the 42 | example enable the `HWCPIPE_BUILD_EXAMPLES` CMake build option. 43 | 44 | ``` 45 | cmake -DHWCPIPE_BUILD_EXAMPLES=ON -B build . 46 | ``` 47 | 48 | # Support 49 | 50 | If you have issues with the library itself, please raise them in the project's GitHub issue tracker. 51 | 52 | If you have any questions about Arm GPUs, application development for Arm GPUs, or general mobile 53 | graphics development or technology please submit them on the [Arm Community graphics forums][1]. 54 | 55 | 56 | - - - 57 | 58 | _Copyright © 2023-2025, Arm Limited and contributors. All rights reserved._ 59 | 60 | [1]: https://community.arm.com/support-forums/f/graphics-gaming-and-vr-forum/ 61 | -------------------------------------------------------------------------------- /backend/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | 4 | minimum_pre_commit_version: 2.9.0 5 | 6 | exclude: "device/src/uapi/.*" 7 | repos: 8 | # global hooks 9 | - repo: https://github.com/pre-commit/pre-commit-hooks 10 | rev: v4.4.0 11 | hooks: 12 | - id: trailing-whitespace 13 | - id: end-of-file-fixer 14 | exclude: "third_party/.*/vendor/.*" 15 | - id: check-ast 16 | - id: check-json 17 | - id: check-yaml 18 | args: [--unsafe] 19 | - id: check-added-large-files 20 | exclude: "third_party/.*/vendor/.*" 21 | - id: check-merge-conflict 22 | - id: debug-statements 23 | - id: mixed-line-ending 24 | exclude: "third_party/.*/vendor/.*" 25 | - repo: https://github.com/PeterMosmans/jenkinslint 26 | rev: v1.0.0 27 | hooks: 28 | - id: jenkinslint 29 | files: Jenkinsfile 30 | - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook 31 | rev: v9.5.0 32 | hooks: 33 | - id: commitlint 34 | stages: [commit-msg] 35 | additional_dependencies: ['@commitlint/config-conventional'] 36 | - repo: https://github.com/pre-commit/mirrors-prettier 37 | rev: v2.7.1 38 | hooks: 39 | - id: prettier 40 | types: [markdown] 41 | - repo: https://github.com/cheshirekow/cmake-format-precommit 42 | rev: v0.6.13 43 | hooks: 44 | - id: cmake-format 45 | - id: cmake-lint 46 | - repo: https://github.com/PyCQA/pylint 47 | rev: v3.0.0a6 48 | hooks: 49 | - id: pylint 50 | additional_dependencies: &pip-packages 51 | - pystache==0.6.0 52 | - PyYAML==6.0 53 | - types-PyYAML==6.0.7 54 | - parameterized==0.8.1 55 | - repo: https://github.com/PyCQA/flake8 56 | rev: 6.0.0 57 | hooks: 58 | - id: flake8 59 | args: ['--max-line-length=120'] 60 | - repo: https://github.com/psf/black 61 | rev: 23.3.0 62 | hooks: 63 | - id: black 64 | - repo: https://github.com/pre-commit/mirrors-mypy 65 | rev: v1.3.0 66 | hooks: 67 | - id: mypy 68 | additional_dependencies: *pip-packages 69 | - repo: https://github.com/pre-commit/mirrors-clang-format 70 | rev: v16.0.4 71 | hooks: 72 | - id: clang-format 73 | - repo: https://github.com/codespell-project/codespell 74 | rev: v2.2.4 75 | hooks: 76 | - id: codespell 77 | exclude: "third_party/.*/vendor/.*" 78 | - repo: https://gitlab.gpu.arm.com/pre-commit/copyright.git 79 | rev: v1.0.0-alpha.16 80 | hooks: 81 | - id: copyright 82 | exclude: (?x)^( 83 | third_party/.*/vendor/.* 84 | |test/workload/src/workload_impl.[ch]pp 85 | )$ 86 | types_or: [c, c++, python] 87 | -------------------------------------------------------------------------------- /backend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021-2022 ARM Limited. 3 | # 4 | # SPDX-License-Identifier: MIT 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | 25 | cmake_minimum_required(VERSION 3.13.5) 26 | 27 | project(hwcpipe2) 28 | 29 | option( 30 | HWCPIPE_ENABLE_TESTS 31 | "If set, build unit tests." 32 | ON 33 | ) 34 | option(HWCPIPE_ENABLE_EXCEPTIONS "If set, c++ exceptions are enabled.") 35 | option( 36 | HWCPIPE_ENABLE_RTTI 37 | "If set, c++ rtti is enabled. Note that exceptions are required for catch2." 38 | ) 39 | option(HWCPIPE_ENABLE_SYMBOLS_VISIBILITY "If set, all symbols are exported.") 40 | option( 41 | HWCPIPE_WALL 42 | "Enable all warnings." 43 | ON 44 | ) 45 | option( 46 | HWCPIPE_WERROR 47 | "Treat compile and link warning as error." 48 | ON 49 | ) 50 | 51 | set(IS_ARM_BUILD FALSE) 52 | if(CMAKE_SYSTEM_PROCESSOR 53 | MATCHES 54 | "^(armv7-a)|(aarch64)$" 55 | ) 56 | set(IS_ARM_BUILD TRUE) 57 | endif() 58 | 59 | include(CMakeDependentOption) 60 | cmake_dependent_option( 61 | HWCPIPE_ENABLE_END_TO_END_TESTS 62 | "If set, build end-to-end tests." 63 | ${IS_ARM_BUILD} 64 | "HWCPIPE_ENABLE_TESTS" 65 | OFF 66 | ) 67 | 68 | option(HWCPIPE_SYSCALL_LIBMALI 69 | "Load syscall function entries from libmali.so for testing." 70 | ) 71 | 72 | if(CMAKE_BUILD_TYPE 73 | AND (NOT 74 | CMAKE_BUILD_TYPE 75 | STREQUAL 76 | "Debug" 77 | ) 78 | ) 79 | set(IS_RELEASE_BUILD YES) 80 | endif() 81 | 82 | option( 83 | HWCPIPE_ENABLE_LTO 84 | "Enable link time optimization. Enabled by default for release builds." 85 | ${IS_RELEASE_BUILD} 86 | ) 87 | 88 | set(CMAKE_CXX_STANDARD 14) 89 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 90 | set(CMAKE_CXX_EXTENSIONS OFF) 91 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 92 | 93 | include(CheckIPOSupported) 94 | check_ipo_supported(RESULT IS_LTO_SUPPORTED OUTPUT error) 95 | 96 | if(IS_LTO_SUPPORTED AND HWCPIPE_ENABLE_LTO) 97 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) 98 | endif() 99 | 100 | if(HWCPIPE_ENABLE_EXCEPTIONS) 101 | add_compile_options("-fexceptions") 102 | else() 103 | add_compile_options("-fno-exceptions") 104 | endif() 105 | 106 | if(HWCPIPE_ENABLE_RTTI) 107 | add_compile_options("-frtti") 108 | else() 109 | add_compile_options("-fno-rtti") 110 | endif() 111 | 112 | if(HWCPIPE_ENABLE_SYMBOLS_VISIBILITY) 113 | add_compile_options("-fvisibility=default") 114 | else() 115 | add_compile_options("-fvisibility=hidden") 116 | endif() 117 | 118 | if(HWCPIPE_WALL) 119 | add_compile_options( 120 | -Wall 121 | -Wextra 122 | -pedantic 123 | -Wno-abi # Silence GCC 7.1 ABI compatibility warning 124 | -Wconversion 125 | ) 126 | endif() 127 | 128 | if(HWCPIPE_WERROR) 129 | add_compile_options( 130 | -Werror 131 | -pedantic-errors 132 | -Wno-abi # Silence GCC 7.1 ABI compatibility warning 133 | ) 134 | add_link_options(-Werror) 135 | endif() 136 | 137 | add_subdirectory(device) 138 | 139 | if(HWCPIPE_ENABLE_TESTS) 140 | enable_testing() 141 | 142 | add_subdirectory(test) 143 | add_subdirectory(third_party/catch2) 144 | endif() 145 | -------------------------------------------------------------------------------- /backend/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Arm Limited 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or 11 | substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | # `HWCPipe 2.0` 2 | 3 | ## Introduction 4 | 5 | Currently access to Hardware Counters is exposed via ioctl interfaces. 6 | That requires some knowledge about driver internals and sometimes about hardware itself. 7 | Every software that needs to access Mali counters needs to interface with internals somwehow. 8 | 9 | HWCPipe 2.0 is a second version of currently existing open source solution maintained by Arm. 10 | Its aim is to support up to date way to interface with the driver. 11 | The library is intended to be more modular than its predecessor and support different use-cases. 12 | -------------------------------------------------------------------------------- /backend/device/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021-2024 ARM Limited. 3 | # 4 | # SPDX-License-Identifier: MIT 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | 25 | add_library( 26 | device STATIC 27 | src/device/handle.cpp 28 | src/device/hwcnt/backend_type.cpp 29 | src/device/hwcnt/reader.cpp 30 | src/device/hwcnt/sampler/detail/backend.cpp 31 | src/device/hwcnt/sampler/kinstr_prfcnt/block_index_remap.cpp 32 | src/device/hwcnt/sampler/kinstr_prfcnt/enum_info_parser.cpp 33 | src/device/hwcnt/sampler/kinstr_prfcnt/metadata_parser.cpp 34 | src/device/instance.cpp 35 | src/device/num_exec_engines.cpp 36 | src/device/product_id.cpp 37 | ) 38 | 39 | target_include_directories(device PUBLIC "include") 40 | 41 | target_compile_definitions(device PRIVATE -DHWCPIPE_DEVICE_BUILDING=1) 42 | 43 | if(HWCPIPE_SYSCALL_LIBMALI) 44 | target_compile_definitions(device PUBLIC -DHWCPIPE_SYSCALL_LIBMALI=1) 45 | target_link_libraries(device PUBLIC ${CMAKE_DL_LIBS}) 46 | endif() 47 | 48 | add_library(device_private INTERFACE) 49 | target_include_directories(device_private INTERFACE "src") 50 | 51 | target_link_libraries( 52 | device 53 | PRIVATE device_private 54 | ) 55 | 56 | if(HWCPIPE_ENABLE_TESTS) 57 | add_subdirectory(test) 58 | endif() 59 | -------------------------------------------------------------------------------- /backend/device/README.md: -------------------------------------------------------------------------------- 1 | # Device 2 | 3 | ## Overview 4 | 5 | The device library provides low level access to the hardware counters data. 6 | The library hides the complexity of different versions of the Mali KMD and 7 | abstracts away hardware specifics. 8 | 9 | The library provides access to: 10 | 11 | - Kernel side hardware counters samplers (manual and periodic) 12 | - Device dependent constants, e.g. number of shader cores, cache slices, cache size, etc. 13 | 14 | ## Usage 15 | 16 | Minimal example: 17 | 18 | ``` 19 | namespace dev = hwcpipe::device; 20 | 21 | // Create Mali device handle. 22 | auto hndl = dev::handle::create(); 23 | assert(hndl && !"Failed to create Mali device handle."); 24 | 25 | // Create Mali device instance. 26 | auto instance = dev::instance::create(*hndl); 27 | assert(instance && !"Failed to create Mali device."); 28 | 29 | // Enable all counter masks and prepare configuration data. 30 | dev::hwcnt::sampler::configuration::enable_map_type enable_map; 31 | enable_map.set(); 32 | dev::hwcnt::sampler::configuration configs[] = { 33 | { dev::hwcnt::block_type::fe, dev::hwcnt::prfcnt_set::primary, enable_map }, 34 | }; 35 | size_t config_len = std::extent::value; 36 | 37 | // Create manual hardware counters sampler. 38 | dev::hwcnt::sampler::manual manual(*instance, configs, config_len); 39 | 40 | // Start accumulating counters in the hardware registers. 41 | manual.accumulation_start(); 42 | 43 | // Request hardware counter samples. 44 | manual.request_sample(0); 45 | 46 | // Wait for the sample completion and hand the sample buffer to the user space. 47 | std::error_code ec; 48 | dev::hwcnt::sample sample{manual.get_reader(), ec}; 49 | 50 | for (const auto block : sample.blocks()) 51 | process_counter_values(block.get_metadata().values); 52 | 53 | // Stop counters accumulation. 54 | manual.accumulation_stop(0); 55 | ``` 56 | -------------------------------------------------------------------------------- /backend/device/include/device/api.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | /** Import hwcpipe::device symbol. */ 28 | #define HWCPIPE_DEVICE_IMPORT __attribute__((visibility("default"))) 29 | /** Export hwcpipe::device symbol. */ 30 | #define HWCPIPE_DEVICE_EXPORT __attribute__((visibility("default"))) 31 | 32 | /** hwcpipe::device API entry */ 33 | #if defined(HWCPIPE_DEVICE_BUILDING) 34 | #define HWCPIPE_DEVICE_API HWCPIPE_DEVICE_EXPORT 35 | #else 36 | #define HWCPIPE_DEVICE_API HWCPIPE_DEVICE_IMPORT 37 | #endif 38 | -------------------------------------------------------------------------------- /backend/device/include/device/constants.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Mali Device constants header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | namespace hwcpipe { 36 | namespace device { 37 | 38 | /** 39 | * Mali Device Constants. 40 | * 41 | * Various properties of a physical Mali GPU. The values here are to be mainly 42 | * used for derived counters computation. 43 | * 44 | * @warning 45 | * Do not use this structure to figure out how many blocks of a type are present. 46 | * Instead, @ref hwcnt::block_extents must be used. 47 | */ 48 | struct constants { 49 | /** GPU id. */ 50 | uint64_t gpu_id; 51 | 52 | /** CSF Firmware version. */ 53 | uint64_t fw_version; 54 | 55 | /** AXI bus width in bits. */ 56 | uint64_t axi_bus_width; 57 | 58 | /** Number of shader cores. */ 59 | uint64_t num_shader_cores; 60 | 61 | /** The shader core mask. */ 62 | uint64_t shader_core_mask; 63 | 64 | /** Number of L2 cache slices. */ 65 | uint64_t num_l2_slices; 66 | 67 | /** L2 cache slice size in bytes. */ 68 | uint64_t l2_slice_size; 69 | 70 | /** Maximum number of execution engines (per core, over all cores). */ 71 | uint64_t num_exec_engines; 72 | 73 | /** Tile size in pixels. */ 74 | uint64_t tile_size; 75 | 76 | /** Warp width. */ 77 | uint64_t warp_width; 78 | }; 79 | 80 | } // namespace device 81 | } // namespace hwcpipe 82 | -------------------------------------------------------------------------------- /backend/device/include/device/handle.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Mali Device Driver handle header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | #include 36 | 37 | namespace hwcpipe { 38 | 39 | /** Device library namespace */ 40 | namespace device { 41 | /** 42 | * @defgroup device Mali Device Driver 43 | * 44 | * The device library interfaces with Mali kernel driver to query: 45 | * - Device constants 46 | * - Hardware counters 47 | */ 48 | 49 | /** 50 | * Mali device driver handle. 51 | * 52 | * The device handle is the main entry point to the device library API. 53 | * The class controls the lifetime of a Mali device driver file descriptor. 54 | * 55 | * The file descriptor is either created internally by calling `open` 56 | * or provided externally. While opened descriptors are closed automatically 57 | * at the destruction time, the external ones will remain open. 58 | * 59 | * @par Example 60 | * @code 61 | * namespace dev = hwcpipe::device; 62 | * // Create a handle for /dev/mali 63 | * auto hdnl = dev::handle::create(); 64 | * @endcode 65 | * 66 | * To call device functions one should create an @ref instance. 67 | */ 68 | class HWCPIPE_DEVICE_API handle { 69 | protected: 70 | /** Default constructor. */ 71 | handle() = default; 72 | 73 | public: 74 | /** Handle pointer. */ 75 | using handle_ptr = std::unique_ptr; 76 | 77 | /** Destructor. */ 78 | virtual ~handle(); 79 | 80 | /** 81 | * Create handle using the default device path. 82 | * 83 | * Opens `/dev/mali${instance_number}` device. 84 | * The device descriptor is owned by the handle and will be 85 | * closed at the destruction time. 86 | * 87 | * @param[in] instance_number The device instance number. 88 | * @return Pointer to the handle created, `nullptr` if failed. 89 | */ 90 | static handle_ptr create(uint32_t instance_number = 0); 91 | 92 | /** 93 | * Create handle using full path to the device. 94 | * 95 | * The device descriptor is owned by the handle and will be 96 | * closed at the destruction time. 97 | * 98 | * @param[in] device_path Path to the device file to open. 99 | * @return Pointer to the handle created, `nullptr` if failed. 100 | */ 101 | static handle_ptr create(const char *device_path); 102 | 103 | /** 104 | * Create handle using external device file descriptor. 105 | * 106 | * The descriptor is _not_ owned by the handle, and therefore, 107 | * will _not_ be closed at the destruction time. The descriptor 108 | * MUST be valid. It is a programming error to pass an invalid 109 | * descriptor. 110 | * 111 | * @param[in] fd Valid device file descriptor. 112 | * @return Pointer to the handle created, `nullptr` if failed. 113 | */ 114 | static handle_ptr from_external_fd(int fd); 115 | }; 116 | 117 | } // namespace device 118 | } // namespace hwcpipe 119 | -------------------------------------------------------------------------------- /backend/device/include/device/hwcnt/block_extents.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Hardware counters block extents header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | namespace hwcpipe { 41 | namespace device { 42 | namespace hwcnt { 43 | 44 | /** Type of the hardware counters values. */ 45 | enum class sample_values_type : uint8_t { 46 | uint32 = 0, /**< Counter values are 32 bit unsigned integers. */ 47 | uint64 = 1, /**< Counter values are 64 bit unsigned integers. */ 48 | }; 49 | 50 | /** 51 | * Blocks extents class. 52 | * 53 | * Stores information about block numbers, counter numbers and 54 | * their types. 55 | */ 56 | class block_extents { 57 | public: 58 | /** Number of block types type. */ 59 | using num_block_types_type = std::underlying_type_t; 60 | 61 | /** Number of block types. */ 62 | static const constexpr num_block_types_type num_block_types = 63 | static_cast(block_type::last) + 1; 64 | 65 | using num_blocks_of_type_type = std::array; 66 | 67 | /** 68 | * Construct block extents. 69 | * 70 | * @param[in] num_blocks_of_type_v Array of number of blocks on per type basis. 71 | * @param[in] counters_per_block Number of counters per block. 72 | * @param[in] values_type Hardware counters values type. 73 | */ 74 | block_extents(num_blocks_of_type_type num_blocks_of_type_v, uint16_t counters_per_block, 75 | sample_values_type values_type) 76 | : num_blocks_of_type_(num_blocks_of_type_v) 77 | , counters_per_block_(counters_per_block) 78 | , values_type_(values_type) {} 79 | 80 | /** Default ctor. */ 81 | block_extents() = default; 82 | /** Default copy ctor. */ 83 | block_extents(const block_extents &) = default; 84 | /** Default assign. */ 85 | block_extents &operator=(const block_extents &) = default; 86 | 87 | /** @return Number of hardware counters blocks. */ 88 | uint8_t num_blocks() const { 89 | uint8_t result{}; 90 | 91 | for (const auto num_blocks : num_blocks_of_type_) 92 | result = static_cast(result + num_blocks); 93 | 94 | return result; 95 | } 96 | 97 | /** 98 | * Number of blocks of a given type. 99 | * 100 | * @param[in] type Block type. 101 | * @return Number of blocks of type @p type. 102 | */ 103 | uint8_t num_blocks_of_type(block_type type) const { return num_blocks_of_type_[static_cast(type)]; } 104 | 105 | /** @return number of counters per block. */ 106 | uint16_t counters_per_block() const { return counters_per_block_; } 107 | 108 | /** @return hardware counters value type. */ 109 | sample_values_type values_type() const { return values_type_; } 110 | 111 | private: 112 | num_blocks_of_type_type num_blocks_of_type_{}; 113 | uint16_t counters_per_block_{}; 114 | sample_values_type values_type_{}; 115 | }; 116 | 117 | } // namespace hwcnt 118 | } // namespace device 119 | } // namespace hwcpipe 120 | -------------------------------------------------------------------------------- /backend/device/include/device/hwcnt/block_metadata.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Hardware counters block metadata header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | namespace hwcpipe { 39 | namespace device { 40 | namespace hwcnt { 41 | 42 | class reader; 43 | 44 | /** Hardware counters block type. */ 45 | enum class block_type : uint8_t { 46 | /** Front End. */ 47 | fe, 48 | /** Tiler. */ 49 | tiler, 50 | /** Memory System. */ 51 | memory, 52 | /** Shader Core. */ 53 | core, 54 | /** CSF Firmware. */ 55 | firmware, 56 | /** Firmware command stream group. */ 57 | csg, 58 | /** First block type. */ 59 | first = fe, 60 | last = csg, 61 | }; 62 | 63 | /** 64 | * Block state during the counters sample time. 65 | * 66 | * @note If no bits are set, the block is in unknown state, 67 | * backend_features::has_power_states, backend_features::has_vm_states 68 | * and backend_features::has_protection_states must be false. 69 | */ 70 | struct block_state { 71 | /** This block was powered on for at least some portion of the sample */ 72 | uint32_t on : 1; 73 | 74 | /** This block was powered off for at least some portion of the sample */ 75 | uint32_t off : 1; 76 | 77 | /** This block was available to this VM for at least some portion of the sample */ 78 | uint32_t available : 1; 79 | 80 | /** This block was not available to this VM for at least some portion of the sample 81 | * Note that no data is collected when the block is not available to the VM. 82 | */ 83 | uint32_t unavailable : 1; 84 | 85 | /** This block was operating in "normal" (non-protected) mode for at least some portion of the sample */ 86 | uint32_t normal : 1; 87 | 88 | /** This block was operating in "protected" mode for at least some portion of the sample. 89 | * Note that no data is collected when the block is in protected mode. 90 | */ 91 | uint32_t protected_mode : 1; 92 | }; 93 | 94 | /** 95 | * Hardware counters block metadata. 96 | * 97 | * A hardware counters sample is structured as an array of block. Each block has its own type 98 | * and index. A block type represent the hardware unit that these counters 99 | * were collected from. And the index is the instance number of this hardware block. 100 | */ 101 | struct block_metadata { 102 | /** Type of this block. */ 103 | block_type type; 104 | 105 | /** Index of this block within the set of blocks of its type. */ 106 | uint8_t index; 107 | 108 | /** Hardware counters set number this block stores. */ 109 | prfcnt_set set; 110 | 111 | /** State of this block during the counters sampling time. */ 112 | block_state state; 113 | 114 | /** 115 | * Hardware counters values array. 116 | * 117 | * The number of array elements is stored in @ref block_extents::counters_per_block. 118 | * The value types are in @ref block_extents::values_type. 119 | * 120 | * Raw pointer to the shared user-kernel memory. 121 | * The values here are only valid between @ref reader::get_sample @ref reader::put_sample calls. 122 | */ 123 | const void *values; 124 | }; 125 | 126 | } // namespace hwcnt 127 | } // namespace device 128 | } // namespace hwcpipe 129 | -------------------------------------------------------------------------------- /backend/device/include/device/hwcnt/blocks_view.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Hardware counters blocks view header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | namespace hwcpipe { 36 | namespace device { 37 | namespace hwcnt { 38 | 39 | /** 40 | * Blocks view. 41 | * 42 | * Allows to iterate over blocks using range-for loop. 43 | * 44 | * Example: 45 | * @code 46 | * for (const auto &block: sample.blocks()) 47 | * handle_block(block); 48 | * @endcode 49 | */ 50 | class blocks_view { 51 | public: 52 | /** Iterator type. */ 53 | using iterator_type = block_iterator; 54 | 55 | /** 56 | * Constructor. 57 | * 58 | * @param[in] r Hardware counters reader. 59 | * @param[in] sample_hndl Sample handle to construct `blocks_view` for. 60 | */ 61 | blocks_view(const reader &r, sample_handle sample_hndl) 62 | : reader_(r) 63 | , sample_hndl_(sample_hndl) {} 64 | 65 | /** @return Iterator pointing to the first block of a sample */ 66 | iterator_type begin() { return iterator_type(reader_, sample_hndl_); } 67 | 68 | /** @return End iterator. */ 69 | iterator_type end() { return iterator_type(); } 70 | 71 | private: 72 | const reader &reader_; 73 | sample_handle sample_hndl_; 74 | }; 75 | 76 | } // namespace hwcnt 77 | } // namespace device 78 | } // namespace hwcpipe 79 | -------------------------------------------------------------------------------- /backend/device/include/device/hwcnt/features.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Hardware counters features header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | namespace hwcpipe { 36 | namespace device { 37 | namespace hwcnt { 38 | 39 | /** 40 | * Features that the kernel-side hardware counters infrastructure supports. 41 | * 42 | * The device library supports different versions of the hardware 43 | * counters ioctl interface. Some of them provide certain counters 44 | * annotation meta-data, and some of them don't. This structure lists 45 | * which features are supported. 46 | * 47 | * @par Example 48 | * @code 49 | * // Check the feature before accessing gpu_cycle 50 | * if (reader.get_features().has_gpu_cycle) 51 | * printf("GPU timestamp = %lu\n", sample.get_metadata().gpu_cycle); 52 | * else 53 | * printf("No GPU Timestamp data!\n"); 54 | * @endcode 55 | */ 56 | struct features { 57 | /** 58 | * True if HWC samples are annotated with the number of 59 | * GPU and shader cores cycles since the last sample. 60 | * 61 | * When true, @ref sample_metadata::gpu_cycle and @ref sample_metadata::sc_cycle 62 | * values are set. 63 | */ 64 | bool has_gpu_cycle; 65 | 66 | /** True if @ref block_metadata::state power values are set. */ 67 | bool has_power_states; 68 | 69 | /** True if @ref block_metadata::state availability values are set. */ 70 | bool has_vm_states; 71 | 72 | /** True if @ref block_metadata::state protected values are set. */ 73 | bool has_protection_states; 74 | 75 | /** 76 | * True if hardware counters back-end can detect sample period stretched due to 77 | * the counters ring buffer overflow. If true, @ref sample_flags::stretched 78 | * value is meaningful. 79 | */ 80 | bool has_stretched_flag; 81 | 82 | /** 83 | * True if overflow behavior is defined. 84 | * 85 | * The defined overflow behavior is: 86 | * When a counter reaches its maximum, the value will saturate when it is incremented, 87 | * i.e. they will stay maximum until sampled. 88 | */ 89 | bool overflow_behavior_defined; 90 | }; 91 | 92 | } // namespace hwcnt 93 | } // namespace device 94 | } // namespace hwcpipe 95 | -------------------------------------------------------------------------------- /backend/device/include/device/hwcnt/prfcnt_set.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Performance counters set header. 29 | */ 30 | #pragma once 31 | 32 | #include 33 | 34 | namespace hwcpipe { 35 | namespace device { 36 | namespace hwcnt { 37 | 38 | /** 39 | * Performance counters set. 40 | * 41 | * The hardware has limited number of registers to accumulate hardware counters 42 | * values. On the other hand, the number of performance counters exceeds the number 43 | * of registers. Therefore we cannot collect all the performance counters all together. 44 | * There are a few different disjoint sets of counters that can be collected 45 | * together in a profiling session. 46 | */ 47 | enum class prfcnt_set : uint8_t { 48 | primary, /**< Primary. */ 49 | secondary, /**< Secondary. */ 50 | tertiary, /**< Tertiary. */ 51 | }; 52 | 53 | } // namespace hwcnt 54 | } // namespace device 55 | } // namespace hwcpipe 56 | -------------------------------------------------------------------------------- /backend/device/include/device/hwcnt/sampler/configuration.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Hardware counters sampler configuration header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | namespace hwcpipe { 39 | namespace device { 40 | namespace hwcnt { 41 | namespace sampler { 42 | 43 | /** 44 | * Per-block counters configuration. 45 | */ 46 | struct configuration { 47 | /** Maximum number of hardware counters per block. */ 48 | static constexpr const size_t max_counters_per_block{128}; 49 | 50 | /** Type used to represent counter numbers bitmask. */ 51 | using enable_map_type = std::bitset; 52 | 53 | /** Block type. */ 54 | block_type type{}; 55 | 56 | /** Performance counters set to activate for this block type. */ 57 | prfcnt_set set{}; 58 | 59 | /** Bitmask of counters numbers to enable for this block type. */ 60 | enable_map_type enable_map{}; 61 | }; 62 | 63 | } // namespace sampler 64 | } // namespace hwcnt 65 | } // namespace device 66 | } // namespace hwcpipe 67 | -------------------------------------------------------------------------------- /backend/device/include/device/instance.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Mali device driver instance header. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | namespace hwcpipe { 40 | namespace device { 41 | 42 | class handle; 43 | 44 | /** 45 | * Mali device driver instance. 46 | * 47 | * @par Example 48 | * @code 49 | * namespace dev = hwcpipe::device; 50 | * // Create an instance for /dev/mali 51 | * auto hndl = dev::handle::create(); 52 | * // Create a device to serve this instance. 53 | * auto instance = dev::instance::create(*hndl); 54 | * // Print GPU id 55 | * const dev::constants c = instance->get_constants(); 56 | * printf("GPU id = %lu\n", c.gpu_id); 57 | * @endcode 58 | */ 59 | class HWCPIPE_DEVICE_API instance { 60 | public: 61 | /** Instance pointer type. */ 62 | using instance_ptr = std::unique_ptr; 63 | 64 | /** Destructor */ 65 | virtual ~instance(); 66 | 67 | /** 68 | * Get GPU device constants. 69 | * 70 | * @return GPU device constants. 71 | */ 72 | virtual constants get_constants() const = 0; 73 | 74 | /** 75 | * Get hardware counters block's extents. 76 | * 77 | * @return The block_extents structure instance. 78 | */ 79 | virtual hwcnt::block_extents get_hwcnt_block_extents() const = 0; 80 | 81 | /** 82 | * Create device instance. 83 | * 84 | * The @p hndl object must outlive the instance created. 85 | * 86 | * @param[in] hndl Device handle. 87 | * @return The device instance created, nullptr if failed. 88 | */ 89 | static instance_ptr create(handle &hndl); 90 | }; 91 | 92 | } // namespace device 93 | } // namespace hwcpipe 94 | -------------------------------------------------------------------------------- /backend/device/include/device/product_id.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Functions to obtain a GPU product ID and query product information. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | namespace hwcpipe { 38 | namespace device { 39 | 40 | /** 41 | * List of all GPU product IDs 42 | */ 43 | enum class product_id { 44 | /* Midgard */ 45 | t60x, 46 | t62x, 47 | t720, 48 | t760, 49 | t820, 50 | t830, 51 | t860, 52 | t880, 53 | /* Bifrost */ 54 | g31, 55 | g51, 56 | g52, 57 | g71, 58 | g72, 59 | g76, 60 | /* Valhall */ 61 | g57, 62 | g57_2, 63 | g68, 64 | g77, 65 | g78, 66 | g78ae, 67 | g310, 68 | g510, 69 | g610, 70 | g615, 71 | g710, 72 | g715, 73 | /* 5th Gen */ 74 | g720, 75 | g620, 76 | g725, 77 | g625, 78 | }; 79 | 80 | /** GPU Family. */ 81 | enum class gpu_family { 82 | /** Midgard GPU family. */ 83 | midgard, 84 | /** Bifrost GPU Family. */ 85 | bifrost, 86 | /** Valhall GPU Family. */ 87 | valhall, 88 | /** 5th Generation GPU Family */ 89 | fifthgen, 90 | }; 91 | 92 | /** GPU front-end type. */ 93 | enum class gpu_frontend { 94 | /** Job manager GPUs. */ 95 | jm, 96 | /** Command stream front-end GPUs. */ 97 | csf, 98 | }; 99 | 100 | /** 101 | * Get the product ID from a raw GPU ID. 102 | * 103 | * @param[in] raw_gpu_id Raw GPU ID as an integer value. 104 | * @return A pair of error code and product ID. 105 | */ 106 | std::pair product_id_from_raw_gpu_id(uint64_t raw_gpu_id); 107 | 108 | /** 109 | * Get the GPU family to which a product belongs. 110 | * 111 | * @param[in] pid Product ID. 112 | * @return GPU family of the product. 113 | */ 114 | gpu_family get_gpu_family(product_id pid); 115 | 116 | /** 117 | * Get the type of job front-end for a product. 118 | * 119 | * @param[in] pid Product ID. 120 | * @return job front-end type of the product. 121 | */ 122 | gpu_frontend get_gpu_frontend(product_id pid); 123 | 124 | } // namespace device 125 | } // namespace hwcpipe 126 | -------------------------------------------------------------------------------- /backend/device/src/device/detail/cast_to_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file cast_to_impl.hpp */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace detail { 36 | 37 | /** @return instance downcasted to its implementation type. */ 38 | inline auto &cast_to_impl(instance &inst) { 39 | // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) 40 | return static_cast &>(inst); 41 | } 42 | 43 | /** @return instance downcasted to its implementation type. */ 44 | inline auto &cast_to_impl(const instance &inst) { 45 | // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) 46 | return static_cast &>(inst); 47 | } 48 | 49 | /** @return handle downcasted to its implementation type. */ 50 | inline auto &cast_to_impl(handle &hndl) { 51 | // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) 52 | return static_cast &>(hndl); 53 | } 54 | 55 | /** @return handle downcasted to its implementation type. */ 56 | inline auto &cast_to_impl(const handle &hndl) { 57 | // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) 58 | return static_cast &>(hndl); 59 | } 60 | 61 | } // namespace detail 62 | } // namespace device 63 | } // namespace hwcpipe 64 | -------------------------------------------------------------------------------- /backend/device/src/device/detail/enum_operators.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file enum_operators.hpp */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | namespace hwcpipe { 32 | namespace device { 33 | namespace detail { 34 | namespace enum_operators { 35 | 36 | template 37 | auto to_underlying(enum_t value) { 38 | using underlying_type = typename std::underlying_type::type; 39 | return static_cast(value); 40 | } 41 | 42 | template 43 | inline typename std::enable_if::value, enum_t &>::type operator++(enum_t &value) { 44 | auto raw_value = to_underlying(value); 45 | ++raw_value; 46 | value = static_cast(raw_value); 47 | return value; 48 | } 49 | 50 | template 51 | inline typename std::enable_if::value, enum_t &>::type operator--(enum_t &value) { 52 | auto raw_value = to_underlying(value); 53 | --raw_value; 54 | value = static_cast(raw_value); 55 | return value; 56 | } 57 | 58 | template 59 | inline typename std::enable_if::value, enum_t>::type operator++(enum_t &value, int) { 60 | const auto prev = value; 61 | ++value; 62 | return prev; 63 | } 64 | 65 | template 66 | inline typename std::enable_if::value, enum_t>::type operator--(enum_t &value, int) { 67 | const auto prev = value; 68 | --value; 69 | return prev; 70 | } 71 | 72 | } // namespace enum_operators 73 | } // namespace detail 74 | } // namespace device 75 | } // namespace hwcpipe 76 | -------------------------------------------------------------------------------- /backend/device/src/device/detail/is_empty_class.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file is_empty_class.hpp is_empty traits header. 27 | */ 28 | 29 | #pragma once 30 | 31 | namespace hwcpipe { 32 | namespace device { 33 | namespace detail { 34 | 35 | /** 36 | * Checks if a class is an empty class. 37 | * 38 | * @note Classes with alignas attributes are not supported. 39 | * 40 | * @par Example 41 | * @code 42 | * class empty {}; 43 | * static_assert(is_empty_class::value, "empty must be an empty class!"); 44 | * @endcode 45 | */ 46 | template 47 | class is_empty_class { 48 | struct ebo : value_t { 49 | int var; 50 | }; 51 | 52 | public: 53 | /** True if the class is empty, false otherwise. */ 54 | static constexpr bool value{sizeof(ebo) == sizeof(int)}; 55 | }; 56 | 57 | /** True if value_t is an empty class, false otherwise. */ 58 | template 59 | constexpr bool is_empty_class_v{is_empty_class::value}; 60 | 61 | } // namespace detail 62 | } // namespace device 63 | } // namespace hwcpipe 64 | -------------------------------------------------------------------------------- /backend/device/src/device/handle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Mali Device Driver handle implementation. 29 | */ 30 | 31 | #include "handle_impl.hpp" 32 | #include "syscall/iface.hpp" 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | 39 | namespace hwcpipe { 40 | namespace device { 41 | 42 | using handle_impl_type = handle_impl; 43 | 44 | handle::~handle() = default; 45 | 46 | handle::handle_ptr handle::create(uint32_t instance_number) { 47 | std::string device_path("/dev/mali" + std::to_string(instance_number)); 48 | int fd = handle_impl_type::open(device_path.c_str()); 49 | 50 | if (fd < 0) 51 | return nullptr; 52 | 53 | return handle::handle_ptr(new handle_impl_type(fd, handle_impl_type::mode::internal)); 54 | } 55 | 56 | handle::handle_ptr handle::create(const char *device_path) { 57 | int fd = handle_impl_type::open(device_path); 58 | 59 | if (fd < 0) 60 | return nullptr; 61 | 62 | return handle::handle_ptr(new handle_impl_type(fd, handle_impl_type::mode::internal)); 63 | } 64 | 65 | handle::handle_ptr handle::from_external_fd(int fd) { 66 | assert(fd >= 0); 67 | return handle::handle_ptr(new handle_impl_type(fd, handle_impl_type::mode::external)); 68 | } 69 | 70 | } // namespace device 71 | } // namespace hwcpipe 72 | -------------------------------------------------------------------------------- /backend/device/src/device/handle_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Mali Device Driver handle implementation. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | #include 36 | 37 | #include 38 | 39 | namespace hwcpipe { 40 | namespace device { 41 | 42 | /** Handle interface implementation. */ 43 | template 44 | class handle_impl : public handle, private syscall_iface_t { 45 | public: 46 | /** Determines how descriptor should be treated. */ 47 | enum class mode { 48 | /** The descriptor is closed at destruction time. */ 49 | internal, 50 | /** the descriptor is kept open at destruction time. */ 51 | external, 52 | }; 53 | 54 | /** 55 | * Handle constructor. 56 | * 57 | * @param[in] fd Device file descriptor. 58 | * @param[in] m Which descriptor handling mode to use. 59 | * @param[in,out] args System calls interface constructor args (unit tests only). 60 | */ 61 | template 62 | handle_impl(int fd, mode m, args_t &&...args) 63 | : syscall_iface_t(std::forward(args)...) 64 | , fd_(fd) 65 | , mode_(m) {} 66 | 67 | ~handle_impl() override { 68 | if (mode_ == mode::internal) 69 | get_syscall_iface().close(fd_); 70 | } 71 | 72 | /** 73 | * Open character device. 74 | * 75 | * @param[in] path The device path. 76 | * @param[in,out] iface System calls interface to use (unit tests only). 77 | * @return Device handle on success, -1 on failure. 78 | */ 79 | template 80 | static int open(const char *path, other_syscall_iface_t &&iface = {}) { 81 | int fd = -1; 82 | std::error_code ec; 83 | 84 | std::tie(ec, fd) = iface.open(path, O_RDONLY); 85 | 86 | if (ec) 87 | return -1; 88 | 89 | bool is_dev = false; 90 | std::tie(ec, is_dev) = iface.is_char_device(fd); 91 | 92 | if (ec || !is_dev) { 93 | iface.close(fd); 94 | return -1; 95 | } 96 | 97 | return fd; 98 | } 99 | 100 | /** 101 | * Get the file descriptor. 102 | * 103 | * @return file descriptor. 104 | */ 105 | int fd() const { return fd_; } 106 | 107 | private: 108 | /** Syscall interface type. */ 109 | using syscall_iface_type = syscall_iface_t; 110 | /** @return syscall interface instance. */ 111 | syscall_iface_type &get_syscall_iface() { return *this; } 112 | 113 | int fd_; 114 | mode mode_; 115 | }; 116 | } // namespace device 117 | } // namespace hwcpipe 118 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/backend_type.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file backend_type.hpp */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | namespace hwcpipe { 41 | namespace device { 42 | namespace hwcnt { 43 | 44 | namespace detail { 45 | class getenv_iface { 46 | public: 47 | static const char *getenv(const char *name) { return ::getenv(name); } 48 | }; 49 | } // namespace detail 50 | 51 | /** 52 | * HWCNT back-end types bit-mask. 53 | * 54 | * The back-end are listed in a priority order (highest to lowest). 55 | */ 56 | enum class backend_type : uint8_t { 57 | /** vinstr available. */ 58 | vinstr, 59 | /** vinstr pre r21 available. */ 60 | vinstr_pre_r21, 61 | /** kinstr_prfcnt available. */ 62 | kinstr_prfcnt, 63 | /** kinstr_prfcnt workaround available. */ 64 | kinstr_prfcnt_wa, 65 | /** kinstr_prfcnt bad available. */ 66 | kinstr_prfcnt_bad, 67 | /** Sentinel. */ 68 | last = kinstr_prfcnt_bad, 69 | }; 70 | 71 | /** Supported back-end types set. */ 72 | using backend_types_set = std::bitset(backend_type::last) + 1>; 73 | 74 | /** 75 | * Parse back-end type from string. 76 | * 77 | * @param[in] str String to parse, must not be NULL. 78 | * @return A pair of error code and back-end type parsed. 79 | */ 80 | std::pair backend_type_from_str(const char *str); 81 | 82 | /** 83 | * Discover which HWCNT back-ends are available for a given kernel version / GPU product id. 84 | * 85 | * @param[in] version Kbase version. 86 | * @param[in] pid GPU product id. 87 | * @return HWCNT back-ends available. 88 | */ 89 | backend_types_set backend_type_discover(const kbase_version &version, product_id pid); 90 | 91 | /** 92 | * Select HWCNT back-end to use. 93 | * 94 | * @param[in] available_types Available HWCNT back-end types. 95 | * @param[in] iface Getenv iface (testing only). 96 | * @return A pair of error code and back-end selected. 97 | */ 98 | template 99 | inline std::pair backend_type_select(backend_types_set available_types, 100 | evnvar_iface_t &&iface = {}) { 101 | const char *iface_str = iface.getenv("HWCPIPE_BACKEND_INTERFACE"); 102 | 103 | if (iface_str != nullptr) { 104 | backend_type desired_type{}; 105 | std::error_code ec; 106 | 107 | std::tie(ec, desired_type) = backend_type_from_str(iface_str); 108 | 109 | if (ec) 110 | return std::make_pair(ec, backend_type{}); 111 | 112 | backend_types_set desired_types_set{}; 113 | desired_types_set.set(static_cast(desired_type)); 114 | 115 | available_types &= desired_types_set; 116 | } 117 | 118 | for (size_t i = 0; i < available_types.size(); ++i) { 119 | if (available_types.test(i)) 120 | return std::make_pair(std::error_code{}, static_cast(i)); 121 | } 122 | 123 | return std::make_pair(std::make_error_code(std::errc::function_not_supported), backend_type{}); 124 | } 125 | 126 | } // namespace hwcnt 127 | } // namespace device 128 | } // namespace hwcpipe 129 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/reader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | 27 | namespace hwcpipe { 28 | namespace device { 29 | namespace hwcnt { 30 | 31 | reader::~reader() = default; 32 | 33 | } // namespace hwcnt 34 | } // namespace device 35 | } // namespace hwcpipe 36 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/base/backend.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file backend.hpp base::backend class. */ 26 | 27 | #pragma once 28 | 29 | #include "backend_args.hpp" 30 | 31 | #include 32 | #include 33 | 34 | namespace hwcpipe { 35 | namespace device { 36 | namespace hwcnt { 37 | namespace sampler { 38 | namespace base { 39 | 40 | /** Base class for sampler backend / reader implementations. */ 41 | template 42 | class backend : public detail::backend, public reader, private syscall_iface_t { 43 | public: 44 | reader &get_reader() override { return *this; } 45 | 46 | protected: 47 | /** Syscall interface type. */ 48 | using syscall_iface_type = syscall_iface_t; 49 | /** Back-end args type. */ 50 | using args_type = backend_args; 51 | /** Counters memory type. */ 52 | using memory_type = typename args_type::memory_type; 53 | 54 | /** Constructor. */ 55 | backend(args_type &&args, const syscall_iface_t &syscall_iface) 56 | : detail::backend() 57 | , reader(args.fd.release(), args.features_v, args.extents) 58 | , syscall_iface_t(syscall_iface) 59 | , period_ns_(args.period_ns) 60 | , memory_(std::move(args.memory)) {} 61 | 62 | ~backend() override { get_syscall_iface().close(fd_); } 63 | 64 | /** Sampler type. */ 65 | enum class sampler_type { 66 | /** Manual sampler. */ 67 | manual, 68 | /** Periodic sampler. */ 69 | periodic, 70 | }; 71 | 72 | /** @return sampler type. */ 73 | sampler_type sampler_type() const { return period_ns_ ? sampler_type::periodic : sampler_type::manual; } 74 | 75 | /** @return syscall iface reference. */ 76 | syscall_iface_type &get_syscall_iface() { return *this; } 77 | 78 | /** Sampling period. 0 for manual sampling. */ 79 | const uint64_t period_ns_{}; 80 | /** Counters memory. */ 81 | memory_type memory_; 82 | }; 83 | 84 | } // namespace base 85 | } // namespace sampler 86 | } // namespace hwcnt 87 | } // namespace device 88 | } // namespace hwcpipe 89 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/base/backend_args.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file backend_args.hpp base::backend constructor arguments. */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace hwcpipe { 35 | namespace device { 36 | namespace hwcnt { 37 | namespace sampler { 38 | namespace base { 39 | 40 | /** Base sampler constructor arguments. */ 41 | template 42 | struct backend_args { 43 | /** Counters buffer memory type. */ 44 | using memory_type = mapped_memory; 45 | /** Filefd guard type. */ 46 | using filefd_guard_type = filefd_guard; 47 | /** Hardware counters fd. */ 48 | filefd_guard_type fd{}; 49 | /** Sampling period (nanoseconds). */ 50 | uint64_t period_ns{}; 51 | /** Hardware counters features. */ 52 | features features_v{}; 53 | /** Block extents. */ 54 | block_extents extents{}; 55 | /** Counters buffer memory. */ 56 | memory_type memory{}; 57 | }; 58 | 59 | } // namespace base 60 | } // namespace sampler 61 | } // namespace hwcnt 62 | } // namespace device 63 | } // namespace hwcpipe 64 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/discard_impl.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file discard_impl.hpp Discard function implementation. */ 26 | 27 | #pragma once 28 | 29 | #include "poll.hpp" 30 | 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace hwcnt { 36 | namespace sampler { 37 | 38 | /** 39 | * Default `reader::discard` implementation. 40 | * 41 | * @param backend Back-end instance. 42 | * @param syscall_iface Syscall interface. 43 | * @param timestamp_iface Timestam interface. 44 | * @return Error code. 45 | */ 46 | template 47 | std::error_code discard_impl(backend_t &backend, syscall_iface_t &&syscall_iface, timestamp_iface_t &×tamp_iface) { 48 | const auto now = timestamp_iface.clock_gettime(); 49 | for (;;) { 50 | std::error_code ec; 51 | bool ready_read{false}; 52 | 53 | std::tie(ec, ready_read) = check_ready_read(backend.get_fd(), syscall_iface); 54 | if (ec) 55 | return ec; 56 | 57 | if (!ready_read) 58 | break; 59 | 60 | sample_metadata sm{}; 61 | sample_handle sample_hndl{}; 62 | 63 | ec = backend.get_sample(sm, sample_hndl); 64 | if (ec) 65 | return ec; 66 | 67 | ec = backend.put_sample(sample_hndl); 68 | if (ec) 69 | return ec; 70 | 71 | /* If samples are produced faster than discarded, this condition 72 | * prevents from infinite looping. 73 | */ 74 | if (sm.timestamp_ns_end >= now) 75 | break; 76 | } 77 | 78 | return {}; 79 | } 80 | 81 | } // namespace sampler 82 | } // namespace hwcnt 83 | } // namespace device 84 | } // namespace hwcpipe 85 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/filefd_guard.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include 28 | 29 | namespace hwcpipe { 30 | namespace device { 31 | namespace hwcnt { 32 | namespace sampler { 33 | 34 | /** Helper to close descriptor on scope exit. */ 35 | template 36 | class filefd_guard : private syscall_iface_t { 37 | public: 38 | /** 39 | * Default construct descriptor guard. 40 | * 41 | * @param[in] iface Syscall interface (testing only). 42 | */ 43 | explicit filefd_guard(syscall_iface_t iface = {}) 44 | : syscall_iface_t(iface) 45 | , fd_(-1) {} 46 | 47 | /** 48 | * Construct descriptor guard. 49 | * 50 | * @param[in] fd Descriptor to manage. 51 | * @param[in] iface Syscall interface (testing only). 52 | */ 53 | filefd_guard(int fd, syscall_iface_t iface = {}) 54 | : syscall_iface_t(iface) 55 | , fd_(fd) {} 56 | 57 | ~filefd_guard() { reset(-1); } 58 | 59 | filefd_guard(const filefd_guard &) = delete; 60 | filefd_guard &operator=(const filefd_guard &) = delete; 61 | 62 | filefd_guard(filefd_guard &&other) 63 | : syscall_iface_t(other) 64 | , fd_(other.release()) {} 65 | 66 | filefd_guard &operator=(filefd_guard &&other) { 67 | static_cast(*this) = other; 68 | 69 | std::swap(fd_, other.fd_); 70 | 71 | return *this; 72 | } 73 | 74 | /** @return managed file descriptor. */ 75 | int get() const { return fd_; } 76 | 77 | /** Reset file handle to manage a new value. 78 | * 79 | * @param[in] fd New file handle to manage. 80 | */ 81 | void reset(int fd) { 82 | if (fd_ >= 0) 83 | this->close(fd_); 84 | fd_ = fd; 85 | } 86 | 87 | /** @return managed file descriptor, and release ownership. */ 88 | int release() { return std::exchange(fd_, -1); } 89 | 90 | private: 91 | int fd_; 92 | }; 93 | 94 | } // namespace sampler 95 | } // namespace hwcnt 96 | } // namespace device 97 | } // namespace hwcpipe 98 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/filter_block_extents.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file filter_block_extents.hpp */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | namespace hwcpipe { 36 | namespace device { 37 | namespace hwcnt { 38 | namespace sampler { 39 | /** 40 | * Filter block extents. 41 | * 42 | * @param[in] extents Extents to filter. 43 | * @param[in] begin Counters configuration begin. 44 | * @param[in] end Counters configuration end. 45 | * @return Pair of error code and block extents filtered. 46 | */ 47 | inline auto filter_block_extents(const block_extents &extents, const configuration *begin, const configuration *end) { 48 | block_extents::num_blocks_of_type_type num_blocks_of_type{}; 49 | 50 | for (auto it = begin; it != end; ++it) { 51 | // Disallow block configuration if it was not advertised by `instance`. 52 | if (extents.num_blocks_of_type(it->type) == 0) 53 | return std::make_pair(std::make_error_code(std::errc::invalid_argument), block_extents{}); 54 | 55 | const auto block_type_idx = static_cast(it->type); 56 | 57 | // Disallow configuring a block twice. 58 | if (num_blocks_of_type[block_type_idx]) 59 | return std::make_pair(std::make_error_code(std::errc::invalid_argument), block_extents{}); 60 | 61 | num_blocks_of_type[block_type_idx] = extents.num_blocks_of_type(it->type); 62 | } 63 | 64 | const block_extents result{num_blocks_of_type, extents.counters_per_block(), extents.values_type()}; 65 | return std::make_pair(std::error_code{}, result); 66 | } 67 | 68 | } // namespace sampler 69 | } // namespace hwcnt 70 | } // namespace device 71 | } // namespace hwcpipe 72 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/kinstr_prfcnt/backend_args.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file backend_args.hpp kinstr_prfcnt::backend constructor arguments. */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | 32 | namespace hwcpipe { 33 | namespace device { 34 | namespace hwcnt { 35 | namespace sampler { 36 | namespace kinstr_prfcnt { 37 | 38 | /** Arguments for `kinstr_prfcnt::backend` constructor. */ 39 | template 40 | struct backend_args { 41 | /** Base args type. */ 42 | using base_args_type = base::backend_args; 43 | /** Counters buffer memory type. */ 44 | using memory_type = typename base_args_type::memory_type; 45 | /** Max number of shader cores blocks. */ 46 | static constexpr size_t max_blocks_sc = 64; 47 | 48 | /** Arguments for `base::backend`. */ 49 | base_args_type base_args; 50 | 51 | /** Shader cores mask. */ 52 | shader_core_bitset sc_mask; 53 | /** Metadata item size. */ 54 | size_t metadata_item_size{}; 55 | }; 56 | 57 | } // namespace kinstr_prfcnt 58 | } // namespace sampler 59 | } // namespace hwcnt 60 | } // namespace device 61 | } // namespace hwcpipe 62 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/kinstr_prfcnt/block_index_remap.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "block_index_remap.hpp" 26 | 27 | namespace hwcpipe { 28 | namespace device { 29 | namespace hwcnt { 30 | namespace sampler { 31 | namespace kinstr_prfcnt { 32 | 33 | constexpr uint8_t block_index_remap::invalid_index; 34 | 35 | } // namespace kinstr_prfcnt 36 | } // namespace sampler 37 | } // namespace hwcnt 38 | } // namespace device 39 | } // namespace hwcpipe 40 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/kinstr_prfcnt/block_index_remap.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file metadata_parser.hpp */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | namespace hwcpipe { 38 | namespace device { 39 | namespace hwcnt { 40 | namespace sampler { 41 | namespace kinstr_prfcnt { 42 | 43 | /** 44 | * Shader core block index remapper. 45 | * 46 | * Old implementation of kinstr_prfcnt interface has a bug. For shader_core 47 | * hardware counters block `block_metadata::block_idx` is set to the 48 | * shader core index rather to an index of the counters block. For example, 49 | * if `core_mask` is `0b1011`, the indices will be 0, 1, and 3. This class 50 | * re-enumerates the shader cores counters blocks s.t. the indexes are 51 | * contiguous. 52 | */ 53 | class block_index_remap { 54 | /** Index type. */ 55 | using index_type = uint8_t; 56 | 57 | public: 58 | /** 59 | * Constructor. 60 | * 61 | * @param sc_mask Shader cores bitset. 62 | */ 63 | block_index_remap(shader_core_bitset sc_mask) { 64 | std::fill(map_.begin(), map_.end(), invalid_index); 65 | 66 | uint8_t blk_index{}; 67 | 68 | for (size_t sc_index = 0; sc_index < sc_mask.size(); ++sc_index) { 69 | if (sc_mask.test(sc_index)) { 70 | map_[sc_index] = blk_index; 71 | ++blk_index; 72 | } 73 | } 74 | } 75 | 76 | /** 77 | * Remap block index. 78 | * 79 | * @param type Block type. 80 | * @param index Index to remap. 81 | * @return A pair of error code and remapped index value. 82 | */ 83 | auto remap(block_type type, index_type index) const { 84 | if (type != block_type::core) 85 | return std::make_pair(std::error_code{}, index); 86 | 87 | if (index >= map_.size() || map_[index] == invalid_index) 88 | return std::make_pair(std::make_error_code(std::errc::invalid_argument), index_type{}); 89 | 90 | return std::make_pair(std::error_code{}, map_[index]); 91 | } 92 | 93 | private: 94 | /** Invalid index value. */ 95 | static constexpr index_type invalid_index = std::numeric_limits::max(); 96 | /** Indices map for remapping. */ 97 | std::array map_{}; 98 | }; 99 | 100 | } // namespace kinstr_prfcnt 101 | } // namespace sampler 102 | } // namespace hwcnt 103 | } // namespace device 104 | } // namespace hwcpipe 105 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/kinstr_prfcnt/construct_block_extents.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include 29 | 30 | namespace hwcpipe { 31 | namespace device { 32 | namespace hwcnt { 33 | namespace sampler { 34 | namespace kinstr_prfcnt { 35 | 36 | /** 37 | * Parse enum info to construct an instance of block extents. 38 | * 39 | * @param[in] ei Enum Info. 40 | * @return Block extents instance parsed from enum info. 41 | */ 42 | inline hwcnt::block_extents construct_block_extents(enum_info ei) { 43 | hwcnt::block_extents block_extents = hwcnt::block_extents{ 44 | ei.num_blocks_of_type, 45 | ei.num_values, 46 | hwcnt::sample_values_type::uint64, 47 | }; 48 | return block_extents; 49 | } 50 | 51 | } // namespace kinstr_prfcnt 52 | } // namespace sampler 53 | } // namespace hwcnt 54 | } // namespace device 55 | } // namespace hwcpipe 56 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/kinstr_prfcnt/enum_info_parser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "enum_info_parser.hpp" 26 | 27 | namespace hwcpipe { 28 | namespace device { 29 | namespace hwcnt { 30 | namespace sampler { 31 | namespace kinstr_prfcnt { 32 | 33 | constexpr enum_info_parser::type2member_type enum_info_parser::type2member; 34 | 35 | } // namespace kinstr_prfcnt 36 | } // namespace sampler 37 | } // namespace hwcnt 38 | } // namespace device 39 | } // namespace hwcpipe 40 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/kinstr_prfcnt/metadata_parser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "metadata_parser.hpp" 26 | 27 | namespace hwcpipe { 28 | namespace device { 29 | namespace hwcnt { 30 | namespace sampler { 31 | namespace kinstr_prfcnt { 32 | 33 | constexpr metadata_parser::type2member_type metadata_parser::type2member; 34 | 35 | } // namespace kinstr_prfcnt 36 | } // namespace sampler 37 | } // namespace hwcnt 38 | } // namespace device 39 | } // namespace hwcpipe 40 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/kinstr_prfcnt/parse_all.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file metadata_parser.hpp */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace hwcnt { 36 | namespace sampler { 37 | namespace kinstr_prfcnt { 38 | 39 | namespace detail { 40 | ///@cond NO_DOCS 41 | template 42 | std::error_code call_on_item(parser_t &parser, const item_t &item, 43 | std::tuple type2member_entry) { 44 | return parser.on_item(item.u.*std::get<1>(type2member_entry)); 45 | } 46 | 47 | template 48 | std::error_code call_on_item(parser_t &parser, const item_t &, std::tuple) { 49 | 50 | return parser.on_item(); 51 | } 52 | 53 | template 54 | std::enable_if_t dispatch_on_item(parser_t &, const item_t &, 55 | std::tuple) { 56 | return std::make_error_code(std::errc::invalid_argument); 57 | } 58 | 59 | template 60 | std::enable_if_t < index_v 61 | dispatch_on_item(parser_t &parser, const item_t &item, std::tuple type2member) { 62 | const auto type2member_entry = std::get(parser_t::type2member); 63 | 64 | if (std::get<0>(type2member_entry) == item.hdr.type) { 65 | return call_on_item(parser, item, std::get(type2member)); 66 | } 67 | 68 | return dispatch_on_item(parser, item, type2member); 69 | } 70 | 71 | ///@endcond NO_DOCS 72 | } // namespace detail 73 | 74 | /** 75 | * Declare mapping from tagged union tag to the union member. 76 | * 77 | * @param[in] item_tag Union member tag. 78 | * @param[in] member_ptr Union member pointer corresponding to the tag. 79 | * @return Declaration data structure. 80 | */ 81 | template 82 | constexpr auto type2member_entry(item_tag_t item_tag, member_ptr_t member_ptr) { 83 | return std::make_tuple(item_tag, member_ptr); 84 | } 85 | 86 | /** 87 | * Declare sentinel item tag. 88 | * 89 | * @param[in] item_tag Sentinel item tag. 90 | * @return Declaration data structure. 91 | */ 92 | template 93 | constexpr auto type2member_entry(item_tag_t item_tag) { 94 | return std::make_tuple(item_tag); 95 | } 96 | 97 | /** 98 | * Parse sequence of tagged unions. 99 | * 100 | * @param[in] begin Unions sequence begin iterator. 101 | * @param[in] end Unions sequence end iterator. 102 | * @param[in,out] parser The parser class. 103 | * @return Parse result. 104 | */ 105 | template 106 | auto parse_all(iterator_t begin, iterator_t end, parser_t &parser) { 107 | std::error_code ec; 108 | 109 | for (auto it = begin; it != end; ++it) { 110 | if (parser.sentinel_parsed()) 111 | return std::make_error_code(std::errc::invalid_argument); 112 | 113 | ec = detail::dispatch_on_item<0>(parser, *it, parser_t::type2member); 114 | 115 | if (ec) 116 | return ec; 117 | } 118 | 119 | return parser.on_done(); 120 | } 121 | 122 | } // namespace kinstr_prfcnt 123 | } // namespace sampler 124 | } // namespace hwcnt 125 | } // namespace device 126 | } // namespace hwcpipe 127 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/poll.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | namespace hwcpipe { 33 | namespace device { 34 | namespace hwcnt { 35 | namespace sampler { 36 | 37 | namespace detail { 38 | 39 | /** 40 | * Poll file descriptor. 41 | * 42 | * @param[in] fd File descriptor to poll. 43 | * @param[in] timeout Polling timeout. -1 to wait forever. 44 | * @param[in] iface Syscall iface (testing only). 45 | * @return A pair of error code and boolean. The boolean is `true` if @p fd is ready. 46 | */ 47 | template 48 | inline auto poll_fd(int fd, int timeout, syscall_iface_t &&iface = {}) { 49 | pollfd fds{}; 50 | 51 | fds.fd = fd; 52 | fds.events = POLLIN; 53 | 54 | int nelems{}; 55 | std::error_code ec; 56 | 57 | static constexpr nfds_t num_fds = 1; 58 | 59 | std::tie(ec, nelems) = iface.poll(&fds, num_fds, timeout); 60 | 61 | return std::make_pair(ec, nelems == num_fds); 62 | } 63 | } // namespace detail 64 | 65 | /** 66 | * Wait for hardware counters sample. 67 | * 68 | * @param[in] fd Hardware counters file descriptor. 69 | * @param[in] iface Syscall iface (testing only). 70 | * @return Error code. 71 | */ 72 | template 73 | inline std::error_code wait_for_sample(int fd, syscall_iface_t &&iface = {}) { 74 | std::error_code ec; 75 | bool ready{}; 76 | 77 | static constexpr int wait_forever = -1; 78 | 79 | std::tie(ec, ready) = detail::poll_fd(fd, wait_forever, std::forward(iface)); 80 | 81 | if (ec) 82 | return ec; 83 | 84 | if (!ready) 85 | return std::make_error_code(std::errc::timed_out); 86 | 87 | return {}; 88 | } 89 | 90 | /** 91 | * Check if a sample is ready to be read. 92 | * 93 | * @param[in] fd Hardware counters file descriptor. 94 | * @param[in] iface Syscall iface (testing only). 95 | * @return A pair of error code and boolean. The boolean is `true` if @p fd is ready. 96 | */ 97 | template 98 | inline auto check_ready_read(int fd, syscall_iface_t &&iface = {}) { 99 | static constexpr int no_wait = 0; 100 | 101 | return detail::poll_fd(fd, no_wait, std::forward(iface)); 102 | } 103 | 104 | } // namespace sampler 105 | } // namespace hwcnt 106 | } // namespace device 107 | } // namespace hwcpipe 108 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/timestamp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file timestamp.hpp 27 | * 28 | * Timestamp querying interface. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | namespace hwcpipe { 39 | namespace device { 40 | namespace hwcnt { 41 | namespace sampler { 42 | 43 | /** Timestamp querying interface. */ 44 | class timestamp_iface { 45 | public: 46 | /** @return clock monotonic raw, if supported, or clock monotonic timestamp. */ 47 | static uint64_t clock_gettime() { 48 | timespec now{}; 49 | #if defined(CLOCK_MONOTONIC_RAW) 50 | ::clock_gettime(CLOCK_MONOTONIC_RAW, &now); 51 | #elif defined(CLOCK_MONOTONIC) 52 | ::clock_gettime(CLOCK_MONOTONIC, &now); 53 | #else 54 | #error "No clock id defined" 55 | #endif 56 | constexpr uint64_t nsec_per_sec = 1000000000; 57 | 58 | return static_cast(now.tv_sec) * nsec_per_sec + static_cast(now.tv_nsec); 59 | } 60 | }; 61 | 62 | static_assert(::hwcpipe::device::detail::is_empty_class::value, 63 | "timestamp_iface must be an empty class."); 64 | 65 | } // namespace sampler 66 | } // namespace hwcnt 67 | } // namespace device 68 | } // namespace hwcpipe 69 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/vinstr/backend_args.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "sample_layout.hpp" 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | namespace hwcpipe { 38 | namespace device { 39 | namespace hwcnt { 40 | namespace sampler { 41 | namespace vinstr { 42 | 43 | /** Arguments for `vinstr::backend` constructor. */ 44 | template 45 | struct backend_args { 46 | /** Base args type. */ 47 | using base_args_type = base::backend_args; 48 | /** Counters buffer memory type. */ 49 | using memory_type = typename base_args_type::memory_type; 50 | 51 | /** Arguments for `base::backend`. */ 52 | base_args_type base_args; 53 | /** Vinstr reader features. */ 54 | ioctl::vinstr::reader_features features{}; 55 | /** Hardware counters buffer size. */ 56 | size_t buffer_size{0}; 57 | /** Sample layout to use. */ 58 | sample_layout sample_layout_v; 59 | /** Default number of buffers in the kernel ring buffer. 60 | * 61 | * Kbase will use `__get_free_pages` to allocate these buffers as a 62 | * physically contiguous memory chunk. When fragmentation is high, 63 | * it may fail to do so. Then we will try to allocate fewer 64 | * power-of-two buffer numbers -- 16, 8, 4 and 2. 65 | */ 66 | static const constexpr size_t max_buffer_count{32}; 67 | }; 68 | 69 | template 70 | constexpr size_t backend_args::max_buffer_count; 71 | 72 | } // namespace vinstr 73 | } // namespace sampler 74 | } // namespace hwcnt 75 | } // namespace device 76 | } // namespace hwcpipe 77 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/vinstr/construct_block_extents.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace hwcpipe { 33 | namespace device { 34 | namespace hwcnt { 35 | namespace sampler { 36 | namespace vinstr { 37 | 38 | /** 39 | * Construct block extents. 40 | * 41 | * @param[in] pid Product ID. 42 | * @param[in] num_l2_slices Number of L2 slices, which will be parsed to determine the number of memory blocks. 43 | * @param[in] num_shader_cores Number of shader cores. 44 | * @return Instance of block extents. 45 | */ 46 | inline hwcnt::block_extents construct_block_extents(product_id pid, uint64_t num_l2_slices, uint64_t num_shader_cores) { 47 | const uint8_t num_memory_blocks = 48 | (hwcpipe::device::hwcnt::sampler::vinstr::is_v4_layout(pid)) ? 1 : static_cast(num_l2_slices); 49 | 50 | hwcnt::block_extents block_extents = hwcnt::block_extents{ 51 | {{ 52 | 1, // num_fe_blocks 53 | 1, // num_tiler_blocks 54 | num_memory_blocks, // num_memory_blocks 55 | static_cast(num_shader_cores), // num_core_blocks 56 | }}, 57 | 64, // counters_per_block 58 | hwcnt::sample_values_type::uint32, // values_type 59 | }; 60 | return block_extents; 61 | } 62 | 63 | } // namespace vinstr 64 | } // namespace sampler 65 | } // namespace hwcnt 66 | } // namespace device 67 | } // namespace hwcpipe 68 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/vinstr/convert.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file convert.hpp 27 | * 28 | * Conversion routines for vinstr back-end. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | 36 | namespace hwcpipe { 37 | namespace device { 38 | namespace hwcnt { 39 | namespace sampler { 40 | namespace vinstr { 41 | 42 | /** 43 | * Convert from hwcpipe enable mask to vinstr enable mask. 44 | * 45 | * @param[in] mask Hwcpipe mask to convert. 46 | * @return vinstr counters mask. 47 | */ 48 | inline uint32_t convert(configuration::enable_map_type mask) { 49 | constexpr size_t vinstr_mask_bitcount = 32; 50 | constexpr size_t counters_per_bit{4}; 51 | constexpr configuration::enable_map_type counters_bit_mask{0b1111}; 52 | 53 | static_assert(vinstr_mask_bitcount * counters_per_bit == mask.size(), "Unexpected bit count."); 54 | 55 | std::bitset result{}; 56 | 57 | for (size_t idx = 0; mask.any(); mask >>= counters_per_bit, idx++) 58 | result[idx] = (mask & counters_bit_mask).any(); 59 | 60 | return static_cast(result.to_ulong()); 61 | } 62 | 63 | /** 64 | * Convert hwcpipe configuration arguments to vinstr setup arguments. 65 | * 66 | * @param[in] begin Begin iterator. 67 | * @param[in] end End iterator. 68 | * @return A pair of error code and `hwcnt_reader_setup` structure. 69 | */ 70 | inline auto convert(const configuration *begin, const configuration *end) { 71 | ioctl::kbase::hwcnt_reader_setup result{}; 72 | 73 | for (auto it = begin; it != end; ++it) { 74 | if (it->set != prfcnt_set::primary) 75 | return std::make_pair(std::make_error_code(std::errc::not_supported), result); 76 | 77 | switch (it->type) { 78 | case block_type::fe: 79 | result.fe_bm |= convert(it->enable_map); 80 | break; 81 | case block_type::tiler: 82 | result.tiler_bm |= convert(it->enable_map); 83 | break; 84 | case block_type::memory: 85 | result.mmu_l2_bm |= convert(it->enable_map); 86 | break; 87 | case block_type::core: 88 | result.shader_bm |= convert(it->enable_map); 89 | break; 90 | case block_type::firmware: 91 | case block_type::csg: 92 | return std::make_pair(std::make_error_code(std::errc::invalid_argument), result); 93 | } 94 | } 95 | 96 | return std::make_pair(std::error_code{}, result); 97 | } 98 | 99 | } // namespace vinstr 100 | } // namespace sampler 101 | } // namespace hwcnt 102 | } // namespace device 103 | } // namespace hwcpipe 104 | -------------------------------------------------------------------------------- /backend/device/src/device/hwcnt/sampler/vinstr/session.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file session.hpp 27 | * 28 | * Vinstr profiling session state. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | namespace hwcpipe { 38 | namespace device { 39 | namespace hwcnt { 40 | namespace sampler { 41 | namespace vinstr { 42 | 43 | /** Vinstr profiling session state class. */ 44 | class session { 45 | public: 46 | /** Default constructor. */ 47 | session() = default; 48 | 49 | /** 50 | * Session constructor. 51 | * 52 | * @param[in] start_ts_ns Session start timestamp (nanoseconds). 53 | * @param[in] user_data_periodic User data for periodic samples. 54 | */ 55 | session(uint64_t start_ts_ns, uint64_t user_data_periodic) 56 | : last_ts_ns_(start_ts_ns) 57 | , user_data_periodic_(user_data_periodic) {} 58 | 59 | /** Default copy constructor. */ 60 | session(const session &) = default; 61 | /** Default assignment operator. */ 62 | session &operator=(const session &) = default; 63 | 64 | /** 65 | * Update last timestamp. 66 | * 67 | * @param[in] ts New timestamp value to store. 68 | * @return Last timestamp (nanoseconds) before the update. 69 | */ 70 | uint64_t update_ts(uint64_t ts) { 71 | assert(last_ts_ns_ < ts); 72 | 73 | return std::exchange(last_ts_ns_, ts); 74 | } 75 | 76 | /** @return user data for periodic samples. */ 77 | uint64_t user_data_periodic() const { return user_data_periodic_; } 78 | 79 | /** 80 | * Track session stop. 81 | * 82 | * @param[in] stop_sample_nr Number of the manual sample that corresponds to 83 | * this session stop. 84 | */ 85 | void stop(uint64_t stop_sample_nr) { 86 | pending_stop_ = true; 87 | stop_sample_nr_ = stop_sample_nr; 88 | } 89 | 90 | /** 91 | * Check if this session state can be erased. 92 | * 93 | * @param[in] manual_sample_nr Number of the manual sample being parsed. 94 | * @return if this session can be removed. 95 | */ 96 | bool can_erase(uint64_t manual_sample_nr) const { 97 | if (!pending_stop_) 98 | return false; 99 | 100 | return manual_sample_nr == stop_sample_nr_; 101 | } 102 | 103 | private: 104 | /** Either session start timestamp or last sample's timestamp. */ 105 | uint64_t last_ts_ns_{}; 106 | /** User data for periodic samples of this session. */ 107 | uint64_t user_data_periodic_{}; 108 | /** True stop() was called for this session, but some samples 109 | * might not have been parsed yet. 110 | */ 111 | bool pending_stop_{}; 112 | /** Number of the manual sample that was taken when this 113 | * session was stopped. 114 | */ 115 | uint64_t stop_sample_nr_{}; 116 | }; 117 | 118 | } // namespace vinstr 119 | } // namespace sampler 120 | } // namespace hwcnt 121 | } // namespace device 122 | } // namespace hwcpipe 123 | -------------------------------------------------------------------------------- /backend/device/src/device/instance.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file 27 | * 28 | * Mali Device Driver instance implementation. 29 | */ 30 | 31 | #include "handle_impl.hpp" 32 | #include "instance_impl.hpp" 33 | #include "syscall/iface.hpp" 34 | 35 | #include 36 | 37 | #include 38 | 39 | #include 40 | 41 | namespace hwcpipe { 42 | namespace device { 43 | 44 | using handle_impl_type = handle_impl; 45 | using instance_impl_type = instance_impl; 46 | 47 | instance::~instance() = default; 48 | 49 | instance::instance_ptr instance::create(handle &hndl) { 50 | const auto &hndl_impl = detail::cast_to_impl(hndl); 51 | 52 | auto result = std::make_unique(hndl_impl.fd()); 53 | if (!result || !result->valid()) 54 | return {}; 55 | 56 | return result; 57 | } 58 | 59 | } // namespace device 60 | } // namespace hwcpipe 61 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kbase/commands.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /* Note, this file is generated, do NOT edit! */ 26 | 27 | #pragma once 28 | 29 | #include "types.hpp" 30 | 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace ioctl { 36 | namespace kbase { 37 | 38 | /** Interface kbase number. */ 39 | constexpr auto iface_number = 0x80; 40 | 41 | namespace command { 42 | 43 | /** Commands describing kbase ioctl interface. */ 44 | enum command_type { 45 | /** Check version compatibility between JM kernel and userspace. */ 46 | version_check_jm = _IOWR(iface_number, 0x0, ::hwcpipe::device::ioctl::kbase::version_check), 47 | /** Check version compatibility between CSF kernel and userspace. */ 48 | version_check_csf = _IOWR(iface_number, 0x34, ::hwcpipe::device::ioctl::kbase::version_check), 49 | /** Set kernel context creation flags. */ 50 | set_flags = _IOW(iface_number, 0x1, ::hwcpipe::device::ioctl::kbase::set_flags), 51 | /** Get GPU properties. */ 52 | get_gpuprops = _IOW(iface_number, 0x3, ::hwcpipe::device::ioctl::kbase::get_gpuprops), 53 | /** Request the global control block of CSF interface capabilities. */ 54 | cs_get_glb_iface = _IOWR(iface_number, 0x33, ::hwcpipe::device::ioctl::kbase::cs_get_glb_iface), 55 | /** Setup HWC dumper/reader. */ 56 | hwcnt_reader_setup = _IOW(iface_number, 0x8, ::hwcpipe::device::ioctl::kbase::hwcnt_reader_setup), 57 | /** Enum Performance counter information. */ 58 | kinstr_prfcnt_enum_info = _IOWR(iface_number, 0x38, ::hwcpipe::device::ioctl::kbase::kinstr_prfcnt_enum_info), 59 | /** Setup HWC dumper/reader. */ 60 | kinstr_prfcnt_setup = _IOWR(iface_number, 0x39, ::hwcpipe::device::ioctl::kbase::kinstr_prfcnt_setup), 61 | }; 62 | 63 | } // namespace command 64 | } // namespace kbase 65 | } // namespace ioctl 66 | } // namespace device 67 | } // namespace hwcpipe 68 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kbase/compare_manual.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kbase/print_manual.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kbase_pre_r21/commands.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /* Note, this file is generated, do NOT edit! */ 26 | 27 | #pragma once 28 | 29 | #include "types.hpp" 30 | 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace ioctl { 36 | namespace kbase_pre_r21 { 37 | 38 | /** Interface kbase_pre_r21 number. */ 39 | constexpr auto iface_number = 0x80; 40 | 41 | namespace command { 42 | 43 | /** Commands describing kbase_pre_r21 ioctl interface. */ 44 | enum command_type { 45 | /** Check version compatibility between JM kernel and userspace. */ 46 | version_check = _IOWR(iface_number, 0x0, ::hwcpipe::device::ioctl::kbase_pre_r21::version_check_args), 47 | /** Set kernel context creation flags. */ 48 | set_flags = _IOWR(iface_number, 0x212, ::hwcpipe::device::ioctl::kbase_pre_r21::set_flags_args), 49 | /** Get GPU properties. */ 50 | get_gpuprops = _IOWR(iface_number, 0x20e, ::hwcpipe::device::ioctl::kbase_pre_r21::uk_gpuprops), 51 | /** Hardware counter reader setup. */ 52 | hwcnt_reader_setup = _IOWR(iface_number, 0x224, ::hwcpipe::device::ioctl::kbase_pre_r21::uk_hwcnt_reader_setup), 53 | }; 54 | 55 | } // namespace command 56 | } // namespace kbase_pre_r21 57 | } // namespace ioctl 58 | } // namespace device 59 | } // namespace hwcpipe 60 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kbase_pre_r21/compare_manual.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "compare.hpp" 28 | 29 | #include 30 | 31 | namespace hwcpipe { 32 | namespace device { 33 | namespace ioctl { 34 | namespace kbase_pre_r21 { 35 | 36 | bool operator==(const version_check_args &lhs, const version_check_args &rhs) { 37 | return (lhs.header.id == rhs.header.id) // 38 | && (lhs.major == rhs.major) // 39 | && (lhs.minor == rhs.minor); // 40 | } 41 | 42 | bool operator==(const set_flags_args &lhs, const set_flags_args &rhs) { 43 | return (lhs.header.id == rhs.header.id) // 44 | && (lhs.create_flags == rhs.create_flags); // 45 | } 46 | 47 | bool operator==(const uk_gpuprops &lhs, const uk_gpuprops &rhs) { 48 | return (lhs.header.id == rhs.header.id) // 49 | && (lhs.props == rhs.props); // 50 | } 51 | 52 | bool operator==(const uk_hwcnt_reader_setup &lhs, const uk_hwcnt_reader_setup &rhs) { 53 | return (lhs.header.id == rhs.header.id) // 54 | && (lhs.buffer_count == rhs.buffer_count) // 55 | && (lhs.jm_bm == rhs.jm_bm) // 56 | && (lhs.shader_bm == rhs.shader_bm) // 57 | && (lhs.tiler_bm == rhs.tiler_bm) // 58 | && (lhs.mmu_l2_bm == rhs.mmu_l2_bm) // 59 | && (lhs.fd == rhs.fd); // 60 | } 61 | 62 | } // namespace kbase_pre_r21 63 | } // namespace ioctl 64 | } // namespace device 65 | } // namespace hwcpipe 66 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kbase_pre_r21/print_manual.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "print.hpp" 28 | 29 | #include 30 | 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace ioctl { 36 | namespace kbase_pre_r21 { 37 | 38 | inline std::ostream &operator<<(std::ostream &os, const version_check_args &value) { 39 | // clang-format off 40 | return os << "version_check_args {\n" // 41 | << debug::indent_level::push // 42 | << debug::indent << ".header.id = " << value.header.id << ",\n" // 43 | << debug::indent << ".major = " << value.major << ",\n" // 44 | << debug::indent << ".minor = " << value.minor << ",\n" // 45 | << debug::indent_level::pop // 46 | << debug::indent << "}"; // 47 | // clang-format on 48 | } 49 | 50 | inline std::ostream &operator<<(std::ostream &os, const set_flags_args &value) { 51 | // clang-format off 52 | return os << "version_check_args {\n" // 53 | << debug::indent_level::push // 54 | << debug::indent << ".header.id = " << value.header.id << ",\n" // 55 | << debug::indent << ".create_flags = " << value.create_flags << ",\n" // 56 | << debug::indent_level::pop // 57 | << debug::indent << "}"; // 58 | // clang-format on 59 | } 60 | 61 | inline std::ostream &operator<<(std::ostream &os, const uk_gpuprops &value) { 62 | // clang-format off 63 | return os << "uk_gpuprops {\n" // 64 | << debug::indent_level::push // 65 | << debug::indent << ".header.id = " << value.header.id << ",\n" // 66 | << debug::indent << ".props = " << value.props << ",\n" // 67 | << debug::indent_level::pop // 68 | << debug::indent << "}"; // 69 | // clang-format on 70 | } 71 | 72 | inline std::ostream &operator<<(std::ostream &os, const uk_hwcnt_reader_setup &value) { 73 | // clang-format off 74 | return os << "uk_hwcnt_reader_setup {\n" // 75 | << debug::indent_level::push // 76 | << debug::indent << ".header.id = " << value.header.id << ",\n" // 77 | << debug::indent << ".buffer_count = " << value.buffer_count << ",\n" // 78 | << debug::indent << ".jm_bm = " << value.jm_bm << ",\n" // 79 | << debug::indent << ".shader_bm = " << value.shader_bm << ",\n" // 80 | << debug::indent << ".tiler_bm = " << value.tiler_bm << ",\n" // 81 | << debug::indent << ".mmu_l2_bm = " << value.mmu_l2_bm << ",\n" // 82 | << debug::indent << ".fd = " << value.fd << ",\n" // 83 | << debug::indent_level::pop // 84 | << debug::indent << "}"; // 85 | // clang-format on 86 | } 87 | 88 | } // namespace kbase_pre_r21 89 | } // namespace ioctl 90 | } // namespace device 91 | } // namespace hwcpipe 92 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kinstr_prfcnt/commands.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /* Note, this file is generated, do NOT edit! */ 26 | 27 | #pragma once 28 | 29 | #include "types.hpp" 30 | 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace ioctl { 36 | namespace kinstr_prfcnt { 37 | 38 | /** Interface kinstr_prfcnt number. */ 39 | constexpr auto iface_number = 0xbf; 40 | 41 | namespace command { 42 | 43 | /** Commands describing kinstr_prfcnt ioctl interface. */ 44 | enum command_type { 45 | /** Issue command. */ 46 | issue_command = _IOW(iface_number, 0x0, ::hwcpipe::device::ioctl::kinstr_prfcnt::control_cmd), 47 | /** Get sample. */ 48 | get_sample = _IOR(iface_number, 0x1, ::hwcpipe::device::ioctl::kinstr_prfcnt::sample_access), 49 | /** Put sample. */ 50 | put_sample = _IOW(iface_number, 0x10, ::hwcpipe::device::ioctl::kinstr_prfcnt::sample_access), 51 | }; 52 | 53 | } // namespace command 54 | } // namespace kinstr_prfcnt 55 | } // namespace ioctl 56 | } // namespace device 57 | } // namespace hwcpipe 58 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/kinstr_prfcnt/compare_manual.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "compare.hpp" 28 | 29 | #include 30 | 31 | namespace hwcpipe { 32 | namespace device { 33 | namespace ioctl { 34 | namespace kinstr_prfcnt { 35 | 36 | bool operator==(const enum_item &lhs, const enum_item &rhs) { 37 | if (lhs.hdr != rhs.hdr) 38 | return false; 39 | 40 | switch (lhs.hdr.type) { 41 | case enum_item::item_type::block: 42 | return lhs.u.block_counter == rhs.u.block_counter; 43 | case enum_item::item_type::request: 44 | return lhs.u.request == rhs.u.request; 45 | case enum_item::item_type::sample_info: 46 | return lhs.u.sample_info == rhs.u.sample_info; 47 | } 48 | 49 | assert(!&"Unknown enum_item::item_type"); 50 | return false; 51 | } 52 | 53 | bool operator==(const metadata_item &lhs, const metadata_item &rhs) { 54 | if (lhs.hdr != rhs.hdr) 55 | return false; 56 | 57 | switch (lhs.hdr.type) { 58 | case metadata_item::item_type::none: 59 | return true; 60 | case metadata_item::item_type::block: 61 | return lhs.u.block_md == rhs.u.block_md; 62 | case metadata_item::item_type::clock: 63 | return lhs.u.clock_md == rhs.u.clock_md; 64 | case metadata_item::item_type::sample: 65 | return lhs.u.sample_md == rhs.u.sample_md; 66 | } 67 | 68 | assert(!&"Unknown metadata_item::item_type"); 69 | return false; 70 | } 71 | 72 | bool operator==(const request_item &lhs, const request_item &rhs) { 73 | if (lhs.hdr != rhs.hdr) 74 | return false; 75 | 76 | switch (lhs.hdr.type) { 77 | case request_item::item_type::none: 78 | return true; 79 | case request_item::item_type::enable: 80 | return lhs.u.req_enable == rhs.u.req_enable; 81 | case request_item::item_type::mode: 82 | return lhs.u.req_mode == rhs.u.req_mode; 83 | case request_item::item_type::scope: 84 | return lhs.u.req_scope == rhs.u.req_scope; 85 | } 86 | 87 | assert(!&"Unknown request_item::item_type"); 88 | return false; 89 | } 90 | 91 | bool operator==(const request_item::request_mode &lhs, const request_item::request_mode &rhs) { 92 | if (lhs.mode != rhs.mode) 93 | return false; 94 | 95 | switch (lhs.mode) { 96 | case request_item::request_mode::sampling_mode::manual: 97 | return true; 98 | case request_item::request_mode::sampling_mode::periodic: 99 | return lhs.mode_config.periodic == rhs.mode_config.periodic; 100 | } 101 | 102 | assert(!&"Unknown request_item::request_mode::sampling_mode"); 103 | return false; 104 | } 105 | 106 | } // namespace kinstr_prfcnt 107 | } // namespace ioctl 108 | } // namespace device 109 | } // namespace hwcpipe 110 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/strided_array_view.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "strided_array_iterator.hpp" 28 | 29 | namespace hwcpipe { 30 | namespace device { 31 | namespace ioctl { 32 | 33 | /** Strided array view. */ 34 | template 35 | class strided_array_view { 36 | public: 37 | /** Iterator type. */ 38 | using iterator_type = strided_array_iterator; 39 | /** Difference type. */ 40 | using difference_type = typename iterator_type::difference_type; 41 | /** Pointer type. */ 42 | using pointer = typename iterator_type::pointer; 43 | 44 | /** 45 | * Construct from pointer, stride and number of elements. 46 | * 47 | * @param[in] ptr First element pointer. 48 | * @param[in] stride Stride between the elements. 49 | * @param[in] num_elements Number of elements in the array. 50 | */ 51 | strided_array_view(pointer ptr, difference_type stride, size_t num_elements) 52 | : ptr_(ptr) 53 | , stride_(stride) 54 | , num_elements_(num_elements) {} 55 | 56 | /** Default copy constructor. */ 57 | strided_array_view(const strided_array_view &) = default; 58 | /** Default assignment operator. */ 59 | strided_array_view &operator=(const strided_array_view &) = default; 60 | 61 | iterator_type begin() { return iterator_type{ptr_, stride_}; } 62 | iterator_type end() { return begin() + static_cast(num_elements_); } 63 | 64 | private: 65 | pointer ptr_; 66 | difference_type stride_; 67 | size_t num_elements_; 68 | }; 69 | 70 | namespace detail { 71 | /** Arguments for constructing a strided array view. */ 72 | struct strided_array_view_args { 73 | ptrdiff_t stride; 74 | size_t num_elements; 75 | }; 76 | 77 | template 78 | strided_array_view operator|(value_t *ptr, const strided_array_view_args &args) { 79 | return strided_array_view{ptr, args.stride, args.num_elements}; 80 | } 81 | } // namespace detail 82 | 83 | /** 84 | * Construct strided array view. 85 | * 86 | * @par Example 87 | * @code 88 | * struct my_struct { 89 | * int field0; 90 | * float field1; 91 | * }; 92 | * 93 | * 94 | * std::array array = get_array(); 95 | * 96 | * // Will iterate over `field1` fields of the array elements. 97 | * for (auto element: &array[0].field1 | strided_array(sizeof(array[0]), array.size())) 98 | * printf("field1 = %f\n", element); 99 | * @endcode 100 | * 101 | * @param stride Offset in bytes between successive elements. 102 | * @param[in] num_elements Number of elements in the array. 103 | */ 104 | inline detail::strided_array_view_args strided_array(ptrdiff_t stride, size_t num_elements) { 105 | return detail::strided_array_view_args{stride, num_elements}; 106 | } 107 | 108 | } // namespace ioctl 109 | } // namespace device 110 | } // namespace hwcpipe 111 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/vinstr/commands.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /* Note, this file is generated, do NOT edit! */ 26 | 27 | #pragma once 28 | 29 | #include "types.hpp" 30 | 31 | #include 32 | 33 | namespace hwcpipe { 34 | namespace device { 35 | namespace ioctl { 36 | namespace vinstr { 37 | 38 | /** Interface vinstr number. */ 39 | constexpr auto iface_number = 0xbe; 40 | 41 | namespace command { 42 | 43 | /** Commands describing vinstr ioctl interface. */ 44 | enum command_type { 45 | /** Get HW version. */ 46 | get_hwver = _IOR(iface_number, 0x0, uint32_t), 47 | /** Get HWCNT dump buffer size. */ 48 | get_buffer_size = _IOR(iface_number, 0x1, uint32_t), 49 | /** Request manual HWCNT dump. */ 50 | dump = _IOW(iface_number, 0x10, uint32_t), 51 | /** Request HWCNT clear. */ 52 | clear = _IOW(iface_number, 0x11, uint32_t), 53 | /** Get hardware counters buffer. */ 54 | get_buffer = _IOR(iface_number, 0x20, ::hwcpipe::device::ioctl::vinstr::reader_metadata), 55 | /** Get hardware counters buffer with cycle counters. */ 56 | get_buffer_with_cycles = _IOR(iface_number, 0x20, ::hwcpipe::device::ioctl::vinstr::reader_metadata_with_cycles), 57 | /** Put hardware counters buffer. */ 58 | put_buffer = _IOW(iface_number, 0x21, ::hwcpipe::device::ioctl::vinstr::reader_metadata), 59 | /** Put hardware counters buffer with cycles. */ 60 | put_buffer_with_cycles = _IOW(iface_number, 0x21, ::hwcpipe::device::ioctl::vinstr::reader_metadata_with_cycles), 61 | /** Set HWCNT sampling interval. Zero for manual sampling. */ 62 | set_interval = _IOW(iface_number, 0x30, uint32_t), 63 | /** Enable HWCNT event. */ 64 | enable_event = _IOW(iface_number, 0x40, ::hwcpipe::device::ioctl::vinstr::reader_event), 65 | /** Disable HWCNT event. */ 66 | disable_event = _IOW(iface_number, 0x41, ::hwcpipe::device::ioctl::vinstr::reader_event), 67 | /** Get HWCNT api version. */ 68 | get_api_version = _IOW(iface_number, 0xff, uint32_t), 69 | /** Get HWCNT api version with features mask. */ 70 | get_api_version_with_features = _IOW(iface_number, 0xff, ::hwcpipe::device::ioctl::vinstr::reader_api_version), 71 | }; 72 | 73 | } // namespace command 74 | } // namespace vinstr 75 | } // namespace ioctl 76 | } // namespace device 77 | } // namespace hwcpipe 78 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/vinstr/compare.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /* Note, this file is generated, do NOT edit! */ 26 | 27 | #pragma once 28 | 29 | // clang-format off 30 | 31 | #include "commands.hpp" 32 | 33 | #include 34 | 35 | namespace hwcpipe { 36 | namespace device { 37 | namespace ioctl { 38 | namespace vinstr { 39 | 40 | inline bool operator==(const reader_metadata_cycles &lhs, const reader_metadata_cycles &rhs); 41 | inline bool operator!=(const reader_metadata_cycles &lhs, const reader_metadata_cycles &rhs) { return !(lhs == rhs); } 42 | inline bool operator==(const reader_metadata &lhs, const reader_metadata &rhs); 43 | inline bool operator!=(const reader_metadata &lhs, const reader_metadata &rhs) { return !(lhs == rhs); } 44 | inline bool operator==(const reader_metadata_with_cycles &lhs, const reader_metadata_with_cycles &rhs); 45 | inline bool operator!=(const reader_metadata_with_cycles &lhs, const reader_metadata_with_cycles &rhs) { return !(lhs == rhs); } 46 | inline bool operator==(const reader_api_version &lhs, const reader_api_version &rhs); 47 | inline bool operator!=(const reader_api_version &lhs, const reader_api_version &rhs) { return !(lhs == rhs); } 48 | 49 | inline bool operator==(const reader_metadata_cycles &lhs, const reader_metadata_cycles &rhs) { 50 | return true // 51 | && lhs.top == rhs.top // 52 | && lhs.shader_cores == rhs.shader_cores // 53 | ; 54 | } 55 | 56 | inline bool operator==(const reader_metadata &lhs, const reader_metadata &rhs) { 57 | return true // 58 | && lhs.timestamp == rhs.timestamp // 59 | && lhs.event_id == rhs.event_id // 60 | && lhs.buffer_idx == rhs.buffer_idx // 61 | ; 62 | } 63 | 64 | inline bool operator==(const reader_metadata_with_cycles &lhs, const reader_metadata_with_cycles &rhs) { 65 | return true // 66 | && lhs.metadata == rhs.metadata // 67 | && lhs.cycles == rhs.cycles // 68 | ; 69 | } 70 | 71 | inline bool operator==(const reader_api_version &lhs, const reader_api_version &rhs) { 72 | return true // 73 | && lhs.version == rhs.version // 74 | && lhs.features == rhs.features // 75 | ; 76 | } 77 | 78 | } // namespace vinstr 79 | } // namespace ioctl 80 | } // namespace device 81 | } // namespace hwcpipe 82 | 83 | #include "compare_manual.hpp" 84 | 85 | // clang-format on 86 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/vinstr/compare_manual.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | -------------------------------------------------------------------------------- /backend/device/src/device/ioctl/vinstr/print_manual.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | -------------------------------------------------------------------------------- /backend/device/src/device/kbase_version.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file kbase_version.hpp Kbase version class. */ 26 | 27 | #pragma once 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | /* Some old versions of header define major and minor macros. 34 | * Here we conveniently un-define them to avoid compilation errors. 35 | */ 36 | 37 | #if defined(major) 38 | #undef major 39 | #endif 40 | 41 | #if defined(minor) 42 | #undef minor 43 | #endif 44 | 45 | namespace hwcpipe { 46 | namespace device { 47 | 48 | /** Kbase ioctl interface type. */ 49 | enum class ioctl_iface_type { 50 | /** Pre R21 release Job manager kernel. */ 51 | jm_pre_r21, 52 | /** Post R21 release Job manager kernel. */ 53 | jm_post_r21, 54 | /** CSF kernel. */ 55 | csf 56 | }; 57 | 58 | /** Check version compatibility between kernel and userspace. */ 59 | class kbase_version { 60 | public: 61 | /** 62 | * Constructor 63 | * 64 | * @param[in] major Major kbase interface version. 65 | * @param[in] minor Minor kbase interface version. 66 | * @param[in] type Kbase interface type. 67 | */ 68 | constexpr kbase_version(uint16_t major, uint16_t minor, ioctl_iface_type type) 69 | : major_(major) 70 | , minor_(minor) 71 | , type_(type) {} 72 | 73 | kbase_version() = default; 74 | kbase_version(const kbase_version &) = default; 75 | kbase_version &operator=(const kbase_version &) = default; 76 | 77 | /** @return major version. */ 78 | uint16_t major() const { return major_; } 79 | /** @return minor version. */ 80 | uint16_t minor() const { return minor_; } 81 | /** @return ioctl interface type. */ 82 | ioctl_iface_type type() const { return type_; } 83 | 84 | private: 85 | /** Major version number. */ 86 | uint16_t major_{0}; 87 | 88 | /** Minor version number. */ 89 | uint16_t minor_{0}; 90 | 91 | /** ioctl interface type info. */ 92 | ioctl_iface_type type_{ioctl_iface_type::csf}; 93 | }; 94 | 95 | inline bool operator==(const kbase_version &lhs, const kbase_version &rhs) { 96 | return (lhs.major() == rhs.major()) // 97 | && (lhs.minor() == rhs.minor()) // 98 | && (lhs.type() == rhs.type()); 99 | } 100 | 101 | inline bool operator!=(const kbase_version &lhs, const kbase_version &rhs) { return !(lhs == rhs); } 102 | 103 | inline bool operator<(const kbase_version &lhs, const kbase_version &rhs) { 104 | assert(lhs.type() == rhs.type()); 105 | return std::make_pair(lhs.major(), lhs.minor()) < std::make_pair(rhs.major(), rhs.minor()); 106 | } 107 | 108 | inline bool operator<=(const kbase_version &lhs, const kbase_version &rhs) { 109 | assert(lhs.type() == rhs.type()); 110 | return std::make_pair(lhs.major(), lhs.minor()) <= std::make_pair(rhs.major(), rhs.minor()); 111 | } 112 | 113 | inline bool operator>(const kbase_version &lhs, const kbase_version &rhs) { 114 | assert(lhs.type() == rhs.type()); 115 | return std::make_pair(lhs.major(), lhs.minor()) > std::make_pair(rhs.major(), rhs.minor()); 116 | } 117 | 118 | inline bool operator>=(const kbase_version &lhs, const kbase_version &rhs) { 119 | assert(lhs.type() == rhs.type()); 120 | return std::make_pair(lhs.major(), lhs.minor()) >= std::make_pair(rhs.major(), rhs.minor()); 121 | } 122 | 123 | } // namespace device 124 | } // namespace hwcpipe 125 | -------------------------------------------------------------------------------- /backend/device/src/device/num_exec_engines.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | namespace hwcpipe { 33 | namespace device { 34 | 35 | /** Argument pack for \c get_num_exec_engines. */ 36 | struct get_num_exec_engines_args { 37 | product_id known_pid{}; //!< The GPU product to query. 38 | uint64_t core_count{}; //!< The number of cores of the GPU. 39 | uint64_t core_features{}; //!< The raw value of the CORE_FEATURES register. 40 | uint32_t thread_features{}; //!< The raw value of the THREAD_FEATURES register. 41 | }; 42 | 43 | /** Decode the number of execution engines for a particular GPU. 44 | * 45 | * @param[in] args Argument pack, see \c get_num_exec_engines_args. 46 | * @param[in] ec Error code. 47 | * @return The maximum number of execution engines per core. 48 | */ 49 | uint8_t get_num_exec_engines(get_num_exec_engines_args &&args, std::error_code &ec); 50 | 51 | } // namespace device 52 | } // namespace hwcpipe 53 | -------------------------------------------------------------------------------- /backend/device/src/device/shader_core_bitset.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** @file shader_core_bitset.hpp Shader core bitest type */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | namespace hwcpipe { 32 | namespace device { 33 | 34 | /** Max shader cores. */ 35 | static constexpr size_t max_shader_cores = 64; 36 | 37 | /** Shader core bitset type. */ 38 | using shader_core_bitset = std::bitset; 39 | } // namespace device 40 | } // namespace hwcpipe 41 | -------------------------------------------------------------------------------- /backend/device/src/device/syscall/funcs/unix.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to 8 | * deal in the Software without restriction, including without limitation the 9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | * sell copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @file unix.hpp Unix system call functions. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #if defined(unix) 39 | #undef unix 40 | #endif 41 | 42 | namespace hwcpipe { 43 | namespace device { 44 | namespace syscall { 45 | namespace funcs { 46 | 47 | /** Unix syscall functions class. */ 48 | struct unix { 49 | template 50 | static auto open(args_t &&...args) { 51 | return ::open(std::forward(args)...); 52 | } 53 | template 54 | static auto close(args_t &&...args) { 55 | return ::close(std::forward(args)...); 56 | } 57 | template 58 | static auto ioctl(args_t &&...args) { 59 | return ::ioctl(std::forward(args)...); 60 | } 61 | 62 | template 63 | static auto mmap(args_t &&...args) { 64 | return ::mmap(std::forward(args)...); 65 | } 66 | 67 | template 68 | static auto munmap(args_t &&...args) { 69 | return ::munmap(std::forward(args)...); 70 | } 71 | }; 72 | 73 | } // namespace funcs 74 | } // namespace syscall 75 | } // namespace device 76 | } // namespace hwcpipe 77 | -------------------------------------------------------------------------------- /cmake/CatchAddTests.cmake: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | set(prefix "${TEST_PREFIX}") 5 | set(suffix "${TEST_SUFFIX}") 6 | set(spec ${TEST_SPEC}) 7 | set(extra_args ${TEST_EXTRA_ARGS}) 8 | set(properties ${TEST_PROPERTIES}) 9 | set(reporter ${TEST_REPORTER}) 10 | set(output_dir ${TEST_OUTPUT_DIR}) 11 | set(output_prefix ${TEST_OUTPUT_PREFIX}) 12 | set(output_suffix ${TEST_OUTPUT_SUFFIX}) 13 | set(script) 14 | set(suite) 15 | set(tests) 16 | 17 | function(add_command NAME) 18 | set(_args "") 19 | # use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments 20 | math(EXPR _last_arg ${ARGC}-1) 21 | foreach(_n RANGE 1 ${_last_arg}) 22 | set(_arg "${ARGV${_n}}") 23 | if(_arg MATCHES "[^-./:a-zA-Z0-9_]") 24 | set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument 25 | else() 26 | set(_args "${_args} ${_arg}") 27 | endif() 28 | endforeach() 29 | set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE) 30 | endfunction() 31 | 32 | # Run test executable to get list of available tests 33 | if(NOT EXISTS "${TEST_EXECUTABLE}") 34 | message(FATAL_ERROR 35 | "Specified test executable '${TEST_EXECUTABLE}' does not exist" 36 | ) 37 | endif() 38 | execute_process( 39 | COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only 40 | OUTPUT_VARIABLE output 41 | RESULT_VARIABLE result 42 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 43 | ) 44 | # Catch --list-test-names-only reports the number of tests, so 0 is... surprising 45 | if(${result} EQUAL 0) 46 | message(WARNING 47 | "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" 48 | ) 49 | elseif(${result} LESS 0) 50 | message(FATAL_ERROR 51 | "Error running test executable '${TEST_EXECUTABLE}':\n" 52 | " Result: ${result}\n" 53 | " Output: ${output}\n" 54 | ) 55 | endif() 56 | 57 | string(REPLACE "\n" ";" output "${output}") 58 | 59 | # Run test executable to get list of available reporters 60 | execute_process( 61 | COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-reporters 62 | OUTPUT_VARIABLE reporters_output 63 | RESULT_VARIABLE reporters_result 64 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 65 | ) 66 | if(${reporters_result} EQUAL 0) 67 | message(WARNING 68 | "Test executable '${TEST_EXECUTABLE}' contains no reporters!\n" 69 | ) 70 | elseif(${reporters_result} LESS 0) 71 | message(FATAL_ERROR 72 | "Error running test executable '${TEST_EXECUTABLE}':\n" 73 | " Result: ${reporters_result}\n" 74 | " Output: ${reporters_output}\n" 75 | ) 76 | endif() 77 | string(FIND "${reporters_output}" "${reporter}" reporter_is_valid) 78 | if(reporter AND ${reporter_is_valid} EQUAL -1) 79 | message(FATAL_ERROR 80 | "\"${reporter}\" is not a valid reporter!\n" 81 | ) 82 | endif() 83 | 84 | # Prepare reporter 85 | if(reporter) 86 | set(reporter_arg "--reporter ${reporter}") 87 | endif() 88 | 89 | # Prepare output dir 90 | if(output_dir AND NOT IS_ABSOLUTE ${output_dir}) 91 | set(output_dir "${TEST_WORKING_DIR}/${output_dir}") 92 | if(NOT EXISTS ${output_dir}) 93 | file(MAKE_DIRECTORY ${output_dir}) 94 | endif() 95 | endif() 96 | 97 | # Parse output 98 | foreach(line ${output}) 99 | set(test ${line}) 100 | # Escape characters in test case names that would be parsed by Catch2 101 | set(test_name ${test}) 102 | foreach(char , [ ]) 103 | string(REPLACE ${char} "\\${char}" test_name ${test_name}) 104 | endforeach(char) 105 | # ...add output dir 106 | if(output_dir) 107 | string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name}) 108 | set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}") 109 | endif() 110 | 111 | # ...and add to script 112 | add_command(add_test 113 | "${prefix}${test}${suffix}" 114 | ${TEST_EXECUTOR} 115 | "${TEST_EXECUTABLE}" 116 | "${test_name}" 117 | ${extra_args} 118 | "${reporter_arg}" 119 | "${output_dir_arg}" 120 | ) 121 | add_command(set_tests_properties 122 | "${prefix}${test}${suffix}" 123 | PROPERTIES 124 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 125 | ${properties} 126 | ) 127 | list(APPEND tests "${prefix}${test}${suffix}") 128 | endforeach() 129 | 130 | # Create a list of all discovered tests, which users may use to e.g. set 131 | # properties on the tests 132 | add_command(set ${TEST_LIST} ${tests}) 133 | 134 | # Write CTest script 135 | file(WRITE "${CTEST_FILE}" "${script}") 136 | -------------------------------------------------------------------------------- /cmake/toolchains/aarch64-android-clang.toolchain.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 by Arm Limited. 2 | # 3 | # SPDX-License-Identifier: MIT 4 | # 5 | 6 | set(ANDROID_TOOLCHAIN_NAME "aarch64-linux-android-clang-" CACHE STRING "" FORCE) 7 | set(ANDROID_ABI "arm64-v8a" CACHE STRING "" FORCE) 8 | 9 | include("${CMAKE_CURRENT_LIST_DIR}/lib/android.toolchain.cmake") -------------------------------------------------------------------------------- /cmake/toolchains/arm-android-clang.toolchain.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 by Arm Limited. 2 | # 3 | # SPDX-License-Identifier: MIT 4 | # 5 | 6 | set(ANDROID_TOOLCHAIN_NAME "arm-linux-androideabi-clang-" CACHE STRING "" FORCE) 7 | set(ANDROID_ABI "armeabi-v7a" CACHE STRING "" FORCE) 8 | 9 | include("${CMAKE_CURRENT_LIST_DIR}/lib/android.toolchain.cmake") -------------------------------------------------------------------------------- /cmake/toolchains/lib/android.toolchain.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2023 by Arm Limited. 2 | # 3 | # SPDX-License-Identifier: MIT 4 | # 5 | 6 | IF((NOT DEFINED CACHE{ANDROID_NDK}) AND (DEFINED ENV{ANDROID_NDK_HOME})) 7 | SET(ANDROID_NDK "$ENV{ANDROID_NDK_HOME}" CACHE FILEPATH "" FORCE) 8 | ENDIF() 9 | 10 | IF((NOT DEFINED CACHE{ANDROID_NDK}) OR (NOT IS_DIRECTORY "$CACHE{ANDROID_NDK}")) 11 | MESSAGE(FATAL_ERROR "ANDROID_NDK is not defined or valid ($CACHE{ANDROID_NDK})") 12 | ENDIF() 13 | 14 | IF((NOT DEFINED CACHE{ANDROID_ABI}) OR ("$CACHE{ANDROID_ABI}" STREQUAL "")) 15 | MESSAGE(FATAL_ERROR "ANDROID_ABI is not defined ($CACHE{ANDROID_ABI})") 16 | ENDIF() 17 | 18 | IF(NOT DEFINED CACHE{ANDROID_NDK_TOOLCHAIN_FILE}) 19 | SET(ANDROID_NDK_TOOLCHAIN_FILE "${ANDROID_NDK}/build/cmake/android.toolchain.cmake" CACHE FILEPATH "" FORCE) 20 | ENDIF() 21 | 22 | IF((NOT EXISTS "$CACHE{ANDROID_NDK_TOOLCHAIN_FILE}") OR (IS_DIRECTORY "$CACHE{ANDROID_NDK_TOOLCHAIN_FILE}")) 23 | MESSAGE(FATAL_ERROR "ANDROID_NDK_TOOLCHAIN_FILE is invalid ($CACHE{ANDROID_NDK_TOOLCHAIN_FILE})") 24 | ENDIF() 25 | 26 | IF(NOT DEFINED CACHE{ANDROID_PLATFORM}) 27 | IF(DEFINED CACHE{ANDROID_NATIVE_API_LEVEL}) 28 | SET(ANDROID_PLATFORM "$CACHE{ANDROID_NATIVE_API_LEVEL}" CACHE STRING "" FORCE) 29 | ELSE() 30 | SET(ANDROID_PLATFORM "android-21" CACHE STRING "" FORCE) 31 | ENDIF() 32 | ENDIF() 33 | 34 | IF(NOT DEFINED CACHE{ANDROID_NATIVE_API_LEVEL}) 35 | SET(ANDROID_NATIVE_API_LEVEL "$CACHE{ANDROID_PLATFORM}" CACHE STRING "" FORCE) 36 | ENDIF() 37 | 38 | IF(NOT ("$CACHE{ANDROID_PLATFORM}" STREQUAL "$CACHE{ANDROID_NATIVE_API_LEVEL}")) 39 | MESSAGE(FATAL_ERROR "Both ANDROID_NATIVE_API_LEVEL and ANDROID_PLATFORM are set and have different values") 40 | ENDIF() 41 | 42 | IF(NOT DEFINED CACHE{ANDROID_NO_UNDEFINED}) 43 | SET(ANDROID_NO_UNDEFINED ON CACHE BOOL "" FORCE) 44 | ENDIF() 45 | 46 | IF(NOT DEFINED CACHE{ANDROID_LD}) 47 | SET(ANDROID_LD "default" CACHE STRING "" FORCE) 48 | ENDIF() 49 | 50 | IF(NOT DEFINED CACHE{ANDROID_STL}) 51 | SET(ANDROID_STL "c++_static" CACHE STRING "" FORCE) 52 | ENDIF() 53 | 54 | INCLUDE("$CACHE{ANDROID_NDK_TOOLCHAIN_FILE}") -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021-2023 Arm Limited. 3 | # 4 | # SPDX-License-Identifier: MIT 5 | # 6 | 7 | add_executable(api-example 8 | api_example.cpp 9 | ) 10 | 11 | target_link_libraries(api-example 12 | PRIVATE hwcpipe 13 | ) 14 | 15 | target_compile_options(api-example 16 | PRIVATE -Werror 17 | -Wswitch-default 18 | -Wswitch-enum 19 | ) -------------------------------------------------------------------------------- /hwcpipe/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2023 Arm Limited. 3 | # 4 | # SPDX-License-Identifier: MIT 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.13.5) 8 | 9 | add_library(hwcpipe 10 | src/error.cpp 11 | src/hwcpipe/detail/counter_database.cpp 12 | src/hwcpipe/all_gpu_counters.cpp 13 | src/hwcpipe/counter_metadata.cpp 14 | src/hwcpipe/derived_functions.cpp 15 | ) 16 | 17 | target_compile_options(hwcpipe 18 | PRIVATE -Werror 19 | -Wswitch-default 20 | -Wswitch-enum 21 | ) 22 | 23 | if(HWCPIPE_PIC) 24 | set_target_properties(hwcpipe PROPERTIES POSITION_INDEPENDENT_CODE ON) 25 | endif() 26 | 27 | target_include_directories(hwcpipe 28 | PUBLIC include 29 | PRIVATE src 30 | ) 31 | 32 | target_link_libraries(hwcpipe 33 | PUBLIC device 34 | ) -------------------------------------------------------------------------------- /hwcpipe/include/hwcpipe/counter_database.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "detail/counter_database.hpp" 10 | #include "hwcpipe/gpu.hpp" 11 | 12 | namespace hwcpipe { 13 | 14 | /** 15 | * @brief Provides access to information about GPU counters. 16 | */ 17 | class counter_database : private detail::counter_database { 18 | public: 19 | counter_database() = default; 20 | 21 | /** 22 | * @brief Returns an iterable object that yields the hwcpipe_counter values 23 | * that are valid for the specified GPU. 24 | * 25 | * @par 26 | * @code 27 | * hwcpipe::gpu gpu(0); 28 | * hwcpipe::counter_database db {}; 29 | * hwcpipe::counter_metadata meta; 30 | * for (hwcpipe_counter counter : db.counters_for_gpu(gpu)) { 31 | * auto ec = db.describe_counter(counter, meta); 32 | * if (ec) { 33 | * continue; 34 | * } 35 | * std::cout << "Counter[" << counter << "] - " << meta.name << std::endl; 36 | * } 37 | * @endcode 38 | * 39 | * @param [in] gpu The GPU to fetch counter information for. 40 | * @return An iterable (provides begin()/end()) list of hwcpipe_counters. 41 | */ 42 | HWCP_NODISCARD auto counters_for_gpu(const gpu &gpu) const { 43 | return detail::counter_database::get_counters_for_gpu(gpu.get_product_id()); 44 | } 45 | 46 | /** 47 | * Retrieves the descriptive information (name, units, etc.) for a counter. 48 | * 49 | * @param [in] counter The hwcpipe_counter to describe. 50 | * @param [out] metadata If the counter is known this will be populated 51 | * with the descriptive information. 52 | * @return If the counter is not known hwcpipe::errc::unknown_counter will 53 | * be returned, otherwise an empty error_code is returned. 54 | */ 55 | HWCP_NODISCARD std::error_code describe_counter(hwcpipe_counter counter, counter_metadata &metadata) const { 56 | return detail::counter_database::describe_counter(counter, metadata); 57 | } 58 | }; 59 | 60 | } // namespace hwcpipe -------------------------------------------------------------------------------- /hwcpipe/include/hwcpipe/detail/assert.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | #if HWCPIPE_TEST 12 | class hwcpipe_assert_exception : public std::exception { 13 | public: 14 | const char *what() { return "hwcpipe assert called"; } 15 | }; 16 | #define HWCPIPE_ASSERT(expr) ((expr) ? (expr) : throw hwcpipe_assert_exception()) 17 | #else 18 | #define HWCPIPE_ASSERT(expr) (assert(expr)) 19 | #endif -------------------------------------------------------------------------------- /hwcpipe/include/hwcpipe/error.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | namespace hwcpipe { 12 | 13 | enum class errc { 14 | invalid_device = 1, 15 | unknown_counter, 16 | invalid_counter_for_device, 17 | // Sampler - construction errors 18 | sampler_config_invalid, 19 | backend_sampler_failure, 20 | backend_creation_failed, 21 | // Sampler - sample process errors 22 | sampling_already_started, 23 | sampling_not_started, 24 | sample_collection_failure, 25 | accumulation_start_failed, 26 | accumulation_stop_failed 27 | }; 28 | 29 | /** 30 | * @brief Returns a reference to HWCPipe's custom error category for use when 31 | * constructing error codes. 32 | */ 33 | const std::error_category &error_category(); 34 | 35 | /** 36 | * @brief Constructs a standard error_code structure for the given HWCpipe error. 37 | * 38 | * @param e The HWCPipe error code. 39 | * @return std::error_code 40 | */ 41 | inline std::error_code make_error_code(errc e) { return {static_cast(e), error_category()}; } 42 | 43 | } // namespace hwcpipe 44 | -------------------------------------------------------------------------------- /hwcpipe/include/hwcpipe/hwcpipe.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | -------------------------------------------------------------------------------- /hwcpipe/include/hwcpipe/types.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #if __cplusplus >= 201703L 12 | #define HWCP_NODISCARD [[nodiscard]] 13 | #else 14 | #define HWCP_NODISCARD __attribute__((warn_unused_result)) 15 | #endif 16 | 17 | namespace hwcpipe { 18 | 19 | using gpu_id_type = uint64_t; 20 | 21 | /** 22 | * Structure that holds descriptive information for a counter. 23 | */ 24 | struct counter_metadata { 25 | const char *name; 26 | const char *units; 27 | }; 28 | 29 | } // namespace hwcpipe -------------------------------------------------------------------------------- /hwcpipe/src/error.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | #include "hwcpipe/error.hpp" 7 | 8 | #include 9 | 10 | namespace hwcpipe { 11 | namespace { 12 | 13 | class hwcpipe_error_category : public std::error_category { 14 | public: 15 | const char *name() const noexcept override { return "HWCPipe error"; } 16 | 17 | std::string message(int code) const noexcept override { 18 | switch (static_cast(code)) { 19 | case errc::invalid_device: 20 | return "Invalid GPU device."; 21 | case errc::unknown_counter: 22 | return "Unknown counter name"; 23 | case errc::invalid_counter_for_device: 24 | return "Counter not supported by GPU"; 25 | case errc::sampler_config_invalid: 26 | return "Invalid configuration (no counters added?)"; 27 | case errc::backend_sampler_failure: 28 | return "Backend sampler failure"; 29 | case errc::backend_creation_failed: 30 | return "Backend creation failed"; 31 | case errc::sampling_already_started: 32 | return "Sampling already started"; 33 | case errc::sampling_not_started: 34 | return "Sampling not started"; 35 | case errc::sample_collection_failure: 36 | return "Sample collection failure"; 37 | case errc::accumulation_start_failed: 38 | return "Failed to start accumulation"; 39 | case errc::accumulation_stop_failed: 40 | return "Failed to stop accumulation"; 41 | 42 | default: 43 | return "Unknown error"; 44 | } 45 | } 46 | }; 47 | 48 | } // unnamed namespace 49 | 50 | const hwcpipe_error_category lib_error_category{}; 51 | 52 | const std::error_category &error_category() { return lib_error_category; } 53 | 54 | } // namespace hwcpipe -------------------------------------------------------------------------------- /hwcpipe/src/hwcpipe/all_gpu_counters.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "device/product_id.hpp" 10 | #include "hwcpipe/detail/internal_types.hpp" 11 | #include "hwcpipe/hwcpipe_counter.h" 12 | 13 | #include 14 | 15 | namespace hwcpipe { 16 | namespace database { 17 | 18 | /** 19 | * A type that maps from counter identifier to the block/offset address for a 20 | * particular GPU. 21 | */ 22 | using gpu_counters_map = std::unordered_map; 23 | 24 | extern const std::unordered_map all_gpu_counters; 25 | 26 | } // namespace database 27 | } // namespace hwcpipe -------------------------------------------------------------------------------- /hwcpipe/src/hwcpipe/counter_metadata.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "hwcpipe/detail/internal_types.hpp" 10 | 11 | #include 12 | 13 | namespace hwcpipe { 14 | namespace database { 15 | 16 | extern const std::array all_counter_metadata; 17 | 18 | } // namespace database 19 | 20 | } // namespace hwcpipe -------------------------------------------------------------------------------- /hwcpipe/src/hwcpipe/detail/counter_database.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #include "device/product_id.hpp" 8 | #include "hwcpipe/all_gpu_counters.hpp" 9 | #include "hwcpipe/counter_metadata.hpp" 10 | #include "hwcpipe/detail/counter_database.hpp" 11 | #include "hwcpipe/error.hpp" 12 | 13 | namespace hwcpipe { 14 | namespace detail { 15 | 16 | bool counter_database::is_gpu_known(device::product_id id) const { 17 | namespace db = hwcpipe::database; 18 | 19 | auto it = db::all_gpu_counters.find(id); 20 | return it != db::all_gpu_counters.end(); 21 | } 22 | 23 | gpu_counter_view counter_database::get_counters_for_gpu(device::product_id id) const { 24 | namespace db = hwcpipe::database; 25 | 26 | auto it = db::all_gpu_counters.find(id); 27 | if (it == db::all_gpu_counters.end()) { 28 | return {*this, {}, {}}; 29 | } 30 | 31 | const auto &counters_map = it->second; 32 | return {*this, counters_map.cbegin(), counters_map.cend()}; 33 | } 34 | 35 | std::error_code counter_database::describe_counter(hwcpipe_counter counter, counter_metadata &metadata) const { 36 | namespace db = hwcpipe::database; 37 | if (static_cast(counter) >= db::all_counter_metadata.size()) { 38 | return hwcpipe::make_error_code(hwcpipe::errc::unknown_counter); 39 | } 40 | 41 | metadata = db::all_counter_metadata[static_cast(counter)]; 42 | return {}; 43 | } 44 | 45 | counter_definition counter_database::get_counter_def(device::product_id id, hwcpipe_counter counter, 46 | std::error_code &ec) { 47 | namespace db = hwcpipe::database; 48 | 49 | auto it = db::all_gpu_counters.find(id); 50 | if (it == db::all_gpu_counters.end()) { 51 | ec = make_error_code(hwcpipe::errc::invalid_device); 52 | return {}; 53 | } 54 | 55 | auto counter_address_it = it->second.find(counter); 56 | if (counter_address_it == it->second.end()) { 57 | ec = make_error_code(errc::invalid_counter_for_device); 58 | return {}; 59 | } 60 | 61 | return counter_address_it->second; 62 | } 63 | 64 | } // namespace detail 65 | } // namespace hwcpipe -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2023-2025 Arm Limited. 3 | # 4 | # SPDX-License-Identifier: MIT 5 | # 6 | 7 | cmake_minimum_required(VERSION 3.13.5) 8 | 9 | # define the Catch2 entrypoint so that we don't have to recompile the implementation for each test group 10 | add_library(catch-main STATIC main.cpp) 11 | target_link_libraries(catch-main PUBLIC catch2) 12 | 13 | function(add_test_target) 14 | cmake_parse_arguments(ADD_TEST_TARGET "" "TARGET" "SOURCES;LIBRARIES" ${ARGN}) 15 | string(REPLACE ";" " " SOURCE_STR "${ADD_TEST_TARGET_SOURCES}") 16 | add_executable(${ADD_TEST_TARGET_TARGET} ${SOURCE_STR}) 17 | 18 | string(REPLACE ";" " " LIBS_STR "${ADD_TEST_TARGET_LIBRARIES}") 19 | target_link_libraries(${ADD_TEST_TARGET_TARGET} ${LIBS_STR} hwcpipe catch-main) 20 | 21 | target_compile_options(${ADD_TEST_TARGET_TARGET} 22 | PRIVATE 23 | -Werror 24 | -Wswitch-default 25 | -Wswitch-enum 26 | -fsanitize=address 27 | -fsanitize=leak 28 | ) 29 | 30 | # Enable AddressSanitizer and LeakSanitizer at link time 31 | target_link_options(${ADD_TEST_TARGET_TARGET} PRIVATE 32 | -fsanitize=address 33 | -fsanitize=leak 34 | ) 35 | 36 | catch_discover_tests(${ADD_TEST_TARGET_TARGET} 37 | REPORTER junit 38 | OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} 39 | OUTPUT_SUFFIX ".result.xml" 40 | ) 41 | endfunction() 42 | 43 | add_test_target(TARGET counter-enumeration-test 44 | SOURCES hwcpipe/counter_enumeration.cpp 45 | ) 46 | 47 | add_test_target(TARGET counter-sampler-test 48 | SOURCES counter-sampler.cpp 49 | ) 50 | 51 | add_test_target(TARGET gpu-instance-test 52 | SOURCES hwcpipe/gpu_instance.cpp 53 | ) 54 | 55 | add_test_target(TARGET hwcpipe-double-test 56 | SOURCES hwcpipe/hwcpipe_double.cpp 57 | ) 58 | 59 | -------------------------------------------------------------------------------- /test/dummy-test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | #include 7 | 8 | #include 9 | 10 | using namespace hwcpipe; 11 | 12 | TEST_CASE("Dummy test") { 13 | auto product = hwcpipe::get_product_id(); 14 | REQUIRE(product.get_gpu_family() == product_id::gpu_family::midgard); 15 | } 16 | -------------------------------------------------------------------------------- /test/hwcpipe/gpu_instance.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #include "device/product_id.hpp" 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace hwcpipe { 18 | 19 | TEST_CASE("gpu_family") { 20 | using pid = device::product_id; 21 | std::stringstream ss{}; 22 | 23 | SECTION("midgard") { 24 | ss << device::gpu_family::midgard; 25 | REQUIRE(ss.str() == "midgard"); 26 | } 27 | 28 | SECTION("bifrost") { 29 | ss << device::gpu_family::bifrost; 30 | REQUIRE(ss.str() == "bifrost"); 31 | } 32 | 33 | SECTION("valhall") { 34 | ss << device::gpu_family::valhall; 35 | REQUIRE(ss.str() == "valhall"); 36 | } 37 | } 38 | 39 | TEST_CASE("gpu_frontend") { 40 | using pid = device::product_id; 41 | std::stringstream ss{}; 42 | 43 | SECTION("jm") { 44 | ss << device::gpu_frontend::jm; 45 | REQUIRE(ss.str() == "jm"); 46 | } 47 | 48 | SECTION("csf") { 49 | ss << device::gpu_frontend::csf; 50 | REQUIRE(ss.str() == "csf"); 51 | } 52 | } 53 | 54 | /* 55 | TEST_CASE("gpu_instance") { 56 | using gpu_instance = detail::gpu_instance_impl; 57 | 58 | mock_handle_factory handle_factory{}; 59 | mock_instance_factory instance_factory{}; 60 | 61 | SECTION("existing device") { 62 | std::error_code ec{}; 63 | gpu_instance dev0{0, ec, handle_factory, instance_factory}; 64 | REQUIRE(!ec); 65 | } 66 | 67 | SECTION("non-existing device") { 68 | std::error_code ec{}; 69 | gpu_instance dev2{2, ec, handle_factory, instance_factory}; 70 | REQUIRE(ec); 71 | } 72 | } 73 | 74 | TEST_CASE("gpu_instance_finder") { 75 | using gpu_instance_finder = detail::gpu_instance_finder_impl; 76 | 77 | mock_handle_factory handle_factory{}; 78 | gpu_instance_finder finder{handle_factory}; 79 | 80 | SECTION("find_all") { 81 | auto devices = finder.find_all(); 82 | 83 | CHECKED_IF(devices.size() == 4) { 84 | REQUIRE(devices[0] == 0); 85 | REQUIRE(devices[1] == 1); 86 | REQUIRE(devices[2] == 4); 87 | REQUIRE(devices[3] == 31); 88 | } 89 | } 90 | } 91 | */ 92 | } // namespace hwcpipe -------------------------------------------------------------------------------- /test/hwcpipe/hwcpipe_double.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #include "hwcpipe/detail/internal_types.hpp" 8 | 9 | #include 10 | 11 | namespace hwcpipe { 12 | namespace detail { 13 | 14 | TEST_CASE("Test hwcpipe_double zero division") { 15 | 16 | SECTION("test 0/0 division") { 17 | detail::hwcpipe_double a{0.0}; 18 | detail::hwcpipe_double b{0.0}; 19 | 20 | double result = a / b; 21 | 22 | REQUIRE(result == 0.0); 23 | } 24 | 25 | SECTION("test >0/0 division") { 26 | detail::hwcpipe_double a{99.99}; 27 | detail::hwcpipe_double b{0.0}; 28 | 29 | double result = a / b; 30 | 31 | REQUIRE(std::isinf(result)); 32 | } 33 | 34 | SECTION("test 0/>0 division") { 35 | detail::hwcpipe_double a{0.0}; 36 | detail::hwcpipe_double b{99.99}; 37 | 38 | double result = a / b; 39 | 40 | REQUIRE(result == 0.0); 41 | } 42 | } 43 | 44 | TEST_CASE("Test hwcpipe_double min and max") { 45 | 46 | SECTION("test max") { 47 | detail::hwcpipe_double max = std::max({5.4, 17.8, 23.6, 999999.99, 46.9, 32.1}); 48 | detail::hwcpipe_double expected = 999999.99; 49 | 50 | REQUIRE(max == expected); 51 | } 52 | 53 | SECTION("test min") { 54 | detail::hwcpipe_double min = std::min({5.4, 17.8, 23.6, 999999.99, 46.9, 32.1}); 55 | detail::hwcpipe_double expected = 5.4; 56 | 57 | REQUIRE(min == expected); 58 | } 59 | } 60 | 61 | TEST_CASE("Test hwcpipe_double addition") { 62 | 63 | SECTION("test add hwcpipe_double") { 64 | detail::hwcpipe_double a{5.3}; 65 | detail::hwcpipe_double b{10.4}; 66 | 67 | double result = a + b; 68 | 69 | REQUIRE(result == 15.7); 70 | } 71 | 72 | SECTION("test add double") { 73 | detail::hwcpipe_double a{9.9}; 74 | double b{1.2}; 75 | 76 | double result = a + b; 77 | 78 | REQUIRE(result == 11.1); 79 | } 80 | 81 | SECTION("test add int") { 82 | detail::hwcpipe_double a{99.99}; 83 | int b{100}; 84 | 85 | double result = a + b; 86 | 87 | REQUIRE(result == 199.99); 88 | } 89 | } 90 | 91 | TEST_CASE("Test hwcpipe_double subtraction") { 92 | 93 | SECTION("test sub hwcpipe_double") { 94 | detail::hwcpipe_double a{12.3}; 95 | detail::hwcpipe_double b{2.2}; 96 | 97 | double result = a - b; 98 | 99 | REQUIRE(result == Approx(10.1)); 100 | } 101 | 102 | SECTION("test sub double") { 103 | detail::hwcpipe_double a{9.9}; 104 | double b{1.2}; 105 | 106 | double result = a - b; 107 | 108 | REQUIRE(result == Approx(8.7)); 109 | } 110 | 111 | SECTION("test sub int") { 112 | detail::hwcpipe_double a{99.99}; 113 | int b{10}; 114 | 115 | double result = a - b; 116 | 117 | REQUIRE(result == 89.99); 118 | } 119 | } 120 | 121 | TEST_CASE("Test hwcpipe_double multiplication") { 122 | 123 | SECTION("test mult hwcpipe_double") { 124 | detail::hwcpipe_double a{12.5}; 125 | detail::hwcpipe_double b{2.5}; 126 | 127 | double result = a * b; 128 | 129 | REQUIRE(result == 31.25); 130 | } 131 | 132 | SECTION("test mult double") { 133 | detail::hwcpipe_double a{10.5}; 134 | double b{4.5}; 135 | 136 | double result = a * b; 137 | 138 | REQUIRE(result == 47.25); 139 | } 140 | 141 | SECTION("test mult int") { 142 | detail::hwcpipe_double a{99.99}; 143 | int b{10}; 144 | 145 | double result = a * b; 146 | 147 | REQUIRE(result == 999.9); 148 | } 149 | } 150 | 151 | TEST_CASE("Test hwcpipe_double division") { 152 | 153 | SECTION("test div hwcpipe_double") { 154 | detail::hwcpipe_double a{12.5}; 155 | detail::hwcpipe_double b{2.5}; 156 | 157 | double result = a / b; 158 | 159 | REQUIRE(result == 5.0); 160 | } 161 | 162 | SECTION("test div double") { 163 | detail::hwcpipe_double a{10.5}; 164 | double b{4.5}; 165 | 166 | double result = a / b; 167 | 168 | REQUIRE(result == Approx(2.33333333333)); 169 | } 170 | 171 | SECTION("test div int") { 172 | detail::hwcpipe_double a{99.99}; 173 | int b{10}; 174 | 175 | double result = a / b; 176 | 177 | REQUIRE(result == Approx(9.999)); 178 | } 179 | } 180 | 181 | } // namespace detail 182 | } // namespace hwcpipe -------------------------------------------------------------------------------- /test/hwcpipe/mock/backend_manual_sampler.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "instance.hpp" 10 | #include "mock_helper.h" 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace hwcpipe { 18 | namespace mock { 19 | 20 | class reader_mock { 21 | public: 22 | MOCK(bool, is_valid, ()); 23 | }; 24 | MOCK_DEFAULT_RET(bool, reader_mock, is_valid, true); 25 | 26 | class backend_manual_sampler_mock { 27 | public: 28 | backend_manual_sampler_mock(const instance_mock &inst, // 29 | const hwcpipe::device::hwcnt::sampler::configuration *config, // 30 | size_t config_len) {} 31 | MOCK(std::error_code, accumulation_start, ()) 32 | MOCK(std::error_code, accumulation_stop, (uint64_t user_data)); 33 | MOCK(std::error_code, request_sample, (uint64_t user_data)); 34 | MOCK(bool, valid, ()); 35 | 36 | operator bool() { return valid(); } 37 | 38 | reader_mock &get_reader() { return reader_; } 39 | 40 | private: 41 | reader_mock reader_; 42 | }; 43 | 44 | MOCK_DEFAULT_RET(std::error_code, backend_manual_sampler_mock, accumulation_start, std::error_code{}); 45 | MOCK_DEFAULT_RET(std::error_code, backend_manual_sampler_mock, accumulation_stop, std::error_code{}); 46 | MOCK_DEFAULT_RET(std::error_code, backend_manual_sampler_mock, request_sample, std::error_code{}); 47 | MOCK_DEFAULT_RET(bool, backend_manual_sampler_mock, valid, true); 48 | 49 | } // namespace mock 50 | } // namespace hwcpipe 51 | -------------------------------------------------------------------------------- /test/hwcpipe/mock/backend_sample.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023-2024 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "backend_manual_sampler.hpp" 10 | #include "catch2/catch.hpp" 11 | #include "mock_helper.h" 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | namespace hwcpipe { 20 | namespace mock { 21 | 22 | namespace hwcnt = device::hwcnt; 23 | 24 | struct block_metadata { 25 | hwcnt::block_type type; 26 | const void *values; 27 | }; 28 | 29 | struct sample_flags { 30 | uint32_t stretched : 1; 31 | uint32_t error : 1; 32 | }; 33 | 34 | struct sample_metadata { 35 | uint64_t user_data; 36 | sample_flags flags; 37 | uint64_t sample_nr; 38 | uint64_t timestamp_ns_begin; 39 | uint64_t timestamp_ns_end; 40 | uint64_t gpu_cycle; 41 | uint64_t sc_cycle; 42 | }; 43 | 44 | class backend_sample_mock { 45 | public: 46 | backend_sample_mock(reader_mock &reader, std::error_code &ec) { 47 | if (!reader.is_valid()) { 48 | ec = std::make_error_code(std::errc::invalid_argument); 49 | } 50 | } 51 | MOCK(sample_metadata, get_metadata, ()); 52 | MOCK(std::vector, blocks, ()); 53 | }; 54 | MOCK_DEFAULT_RET(sample_metadata, backend_sample_mock, get_metadata, {}); 55 | MOCK_DEFAULT_RET(std::vector, backend_sample_mock, blocks, {}); 56 | 57 | } // namespace mock 58 | } // namespace hwcpipe 59 | -------------------------------------------------------------------------------- /test/hwcpipe/mock/handle.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "mock_helper.h" 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace hwcpipe { 18 | namespace mock { 19 | 20 | class handle_mock { 21 | public: 22 | using handle_ptr = std::unique_ptr; 23 | 24 | handle_mock() = default; 25 | 26 | static bool return_valid_instance; 27 | static handle_ptr create(int device_number) { 28 | if (!return_valid_instance) { 29 | return_valid_instance = true; 30 | return nullptr; 31 | } 32 | return std::make_unique(); 33 | } 34 | }; 35 | bool handle_mock::return_valid_instance = true; 36 | 37 | } // namespace mock 38 | } // namespace hwcpipe 39 | -------------------------------------------------------------------------------- /test/hwcpipe/mock/instance.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "handle.hpp" 10 | #include "mock_helper.h" 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace hwcpipe { 19 | namespace mock { 20 | 21 | using sample_values_type = device::hwcnt::sample_values_type; 22 | 23 | class block_extents_mock { 24 | public: 25 | MOCK(sample_values_type, values_type, ()); 26 | }; 27 | MOCK_DEFAULT_RET(sample_values_type, block_extents_mock, values_type, sample_values_type::uint32); 28 | 29 | class instance_mock { 30 | public: 31 | using instance_ptr = std::unique_ptr; 32 | 33 | static bool return_valid_instance; 34 | 35 | static instance_ptr create(handle_mock &hndl) { 36 | if (!return_valid_instance) { 37 | return_valid_instance = true; 38 | return nullptr; 39 | } 40 | return std::make_unique(); 41 | } 42 | 43 | instance_mock() = default; 44 | 45 | MOCK(block_extents_mock, get_hwcnt_block_extents, ()); 46 | MOCK(device::constants, get_constants, ()); 47 | }; 48 | 49 | bool instance_mock::return_valid_instance = true; 50 | 51 | MOCK_DEFAULT_RET(block_extents_mock, instance_mock, get_hwcnt_block_extents, {}); 52 | MOCK_DEFAULT_RET(device::constants, instance_mock, get_constants, {}); 53 | 54 | } // namespace mock 55 | } // namespace hwcpipe 56 | -------------------------------------------------------------------------------- /test/hwcpipe/mock/mock_helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | #pragma once 7 | 8 | /** 9 | * @param RETURN_TYPE return type of mock function. 10 | * @param FUNC_NAME function name. 11 | * @param ARGS function arguments(function prototype). 12 | * 13 | * @par Example 14 | * @code 15 | * //To mock a function with the following prototype 16 | * // void set_id (char* name, int id) 17 | * //MOCK() should be called as following 18 | * MOCK(void, set_id, (char* name, int id)); 19 | * @endcode 20 | */ 21 | #define MOCK(RETURN_TYPE, FUNC_NAME, ARGS) \ 22 | static RETURN_TYPE FUNC_NAME##_default_return_value; \ 23 | static RETURN_TYPE FUNC_NAME##_return_value; \ 24 | RETURN_TYPE FUNC_NAME ARGS { \ 25 | RETURN_TYPE ret_value = FUNC_NAME##_return_value; \ 26 | FUNC_NAME##_return_value = FUNC_NAME##_default_return_value; \ 27 | return ret_value; \ 28 | } 29 | 30 | /** 31 | * @param RETURN_TYPE return type of mock function. 32 | * @param CLASS_NAME Name of the class containing the mocked function. 33 | * @param FUNC_NAME function name. 34 | * @param DEFAULT_RET_VAL default value to return from function 35 | * if EXPECT_CALL() is not called. 36 | * @note this funciton must be called in a file scope but not in a 37 | * class scope. 38 | */ 39 | #define MOCK_DEFAULT_RET(RETURN_TYPE, CLASS_NAME, FUNC_NAME, DEFAULT_RET_VAL) \ 40 | RETURN_TYPE CLASS_NAME::FUNC_NAME##_return_value = DEFAULT_RET_VAL; \ 41 | RETURN_TYPE CLASS_NAME::FUNC_NAME##_default_return_value = DEFAULT_RET_VAL; 42 | 43 | /** 44 | * @param CLASS_NAME Name of the class containing the mocked function. 45 | * @param FUNC_NAME function Name 46 | * @param RETURN_VALUE Return value of expected call 47 | */ 48 | #define EXPECT_CALL(CLASS_NAME, FUNC_NAME, RETURN_VALUE) CLASS_NAME::FUNC_NAME##_return_value = RETURN_VALUE 49 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Arm Limited. 3 | * 4 | * SPDX-License-Identifier: MIT 5 | */ 6 | #define CATCH_CONFIG_MAIN 7 | #include 8 | -------------------------------------------------------------------------------- /third_party/.clang-format: -------------------------------------------------------------------------------- 1 | DisableFormat: true 2 | SortIncludes: false 3 | -------------------------------------------------------------------------------- /third_party/.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*' 2 | -------------------------------------------------------------------------------- /third_party/catch2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021 ARM Limited. 3 | # 4 | # SPDX-License-Identifier: MIT 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | 25 | add_library(catch2 INTERFACE) 26 | target_include_directories(catch2 INTERFACE "vendor") 27 | target_compile_options(catch2 INTERFACE "-fexceptions") 28 | 29 | if(ANDROID) 30 | target_link_libraries(catch2 INTERFACE log) 31 | endif() 32 | -------------------------------------------------------------------------------- /third_party_licenses.txt: -------------------------------------------------------------------------------- 1 | 2 | # License 3 | 4 | This project contains code from other projects listed below. The original license 5 | text is included in those source files. 6 | 7 | * CMake files aiding the use of the Catch2 testing library, licensed under 8 | the BSD-3-Clause license. See 9 | * cmake/Catch.cmake 10 | * cmake/CatchAddTests.cmake 11 | * The Catch2 header 'catch2/catch.hpp' used by tests, licensed under the 12 | Boost Software License, Version 1.0. See 13 | * third_party/catch2/vendor/catch2/catch.hpp 14 | 15 | --------------------------------------------------------------------------------